Django:如何防止视图同时被调用两次?

3 投票
3 回答
6135 浏览
提问于 2025-04-16 20:24

在我们的Django应用程序中,有个功能可以显示一个链接,用来从我们的版本控制系统刷新一些信息。这个链接很简单,当用户点击这个链接时,系统会去版本控制那里获取信息,然后把这些信息和数据库里的数据进行对比,最后更新数据库。

最近有个用户对一个资产点击了“刷新”按钮两次。这导致这个链接被点击了两次,所以相关的操作也执行了两次,结果在我们的数据库里出现了重复的记录。

我们需要想办法避免用户点击这个按钮两次。我们是不是应该把链接换成一个JavaScript按钮?或者在用户第一次点击时,在请求的会话中设置一个标记,等操作完成后再取消这个标记,每次刷新时都检查这个标记?这只是两个看起来可行的想法,但我其实不太确定。

3 个回答

-1

这是最好的解决办法,不过你可以通过给按钮添加一个禁用属性来让它在点击时失效,设置这个属性为'true'。

如果你使用jQuery的话,可以这样写:

$('#yourButtonId').attr("disabled", true);

0
from django.views import View
from django.shortcuts import render, redirect 

class MyView(View):
    def get(self, request):
         return render(request, 'get.html')
    def post(self, request):
        # handle your post here
        # maybe you had a form that was filled, handle it here
        # then instead of returning a HttpResponse
        # use a redirect, that way, a refresh won't result in the 
        # post method been called twice. 
        # note if you want, you can also safely redirect to the same view
        return redirect('/my-login-view')

在查看Django的代码时,发现重定向函数可以接收以下几种参数:
1. 一个模型
2. 一个视图名称
3. 一个网址

4

你应该使用 POST 请求,然后再进行重定向,真的。

另外,为了防止用户重复提交,你可以参考这个问题中的解决方案:有没有库可以防止Django中重复提交表单?。你可以在 request.session 中存储一个键 refreshing_vcs,然后在你的视图中检查它的值。如果数据已经在刷新中,那么你可以把用户重定向到另一个页面,并告诉他们稍等一下。

还有一种完全不同的方法是设置一个 django-celery 任务(或者简单使用 cron)来定期自动执行更新,但我不确定这是否符合你的需求。

撰写回答