我使用的是尽可能少的自定义模板和javascript代码的Python Django Admin。
有没有一种方法可以点击特定的按钮(或表单debounce )?
例如,如果用户在保存按钮上点击了两次(在短时间内),则应该只进行一次调用。
发布于 2020-05-21 06:46:35
如果您不需要任何自定义模板或javascript,一种方法是对该按钮将要发送请求的任何视图进行速率限制。例如,“保存”按钮将向change_view视图发送一个请求,因此您可以对此设置一个速率限制器。像这样的东西应该是有效的:
from ratelimit.decorators import ratelimit
class YourAdminClass(admin.ModelAdmin):
@ratelimit(key='ip', rate='1/s')
def change_view(elf, request, object_id, form_url='', extra_context=None):
# anything else you want to do
return super().change_view(request, object_id, form_url, extra_context)对于任何给定的IP地址,这将允许每秒最多1个。注意:您将需要安装Django Ratelimit。另外,请注意,我从来没有亲自使用过这个库,它只是我在谷歌上搜索时出现的第一个库。
然而..。
为什么你需要这个特殊的特性。Django管理界面永远不应该用作面向客户的站点。唯一使用它的人应该是你公司的人/你为自己制作网站的公司里的人。IMO,它应该只被其他开发人员使用,但可能并不是所有的上下文都是这样的,也许在您的上下文中也不是这样。考虑到所有这些,问问你自己,这是否是你真正需要的功能。
发布于 2020-05-22 21:55:32
我找到了一个解决方案。它不是理想的(我讨厌它),但它是有效的。
我不得不写一些JS代码。幸运的是,django管理模板已经扩展了,所以我不得不在里面放一行:
<script type="text/javascript" src="{% static "admin/js/debounce_form.js" %}"></script>debounce_form.js看起来像这样:
(function ($) {
function debounce(wait) {
const STATUS_PENDING = 1;
const STATUS_DONE = 2;
return {
status: STATUS_PENDING,
timeout: null,
isDone: function(){
return this.state === STATUS_DONE;
},
reset: function() {
this.status = STATUS_PENDING;
},
execute: function(target) {
args = this;
var later = function() {
args.timeout = null;
args.status = STATUS_DONE;
target.submit();
};
args.status = STATUS_PENDING;
clearTimeout(this.timeout);
args.timeout = setTimeout(later, wait);
}
}
}
var submit = debounce(250);
$( "form" ).submit(function( e ) {
// debounce multiple form submission
if (submit.isDone() === false) {
e.preventDefault();
e.stopPropagation();
submit.execute(e.target);
return;
}
submit.reset();
});})(django.jQuery);
https://stackoverflow.com/questions/61915691
复制相似问题