@csrf_exempt 在 Django 1.4 中停止工作

Posted

技术标签:

【中文标题】@csrf_exempt 在 Django 1.4 中停止工作【英文标题】:@csrf_exempt stopped working in Django 1.4 【发布时间】:2012-05-02 09:27:02 【问题描述】:

我有以下代码,在 Django 1.2.5 中运行良好:

from django.views.decorators.csrf import csrf_exempt

class ApiView(object):
    def __call__(self, request, *args, **kwargs):
        method = request.method.upper()
        return getattr(self, method)(request, *args, **kwargs)

@csrf_exempt
class MyView(ApiView):

    def POST(self):
       # (...)
       return HttpResponse(json.dumps(True), mimetype="text/javascript")

但是当我升级到 Django 1.4 时,我开始收到 403 禁止,并显示“CSRF 验证失败”消息。

为什么 @csrf_exempt 装饰器不起作用?

网址定义为:

from django.conf.urls.defaults import *
from django.views.decorators.csrf import csrf_exempt

import views

urlpatterns = patterns('',
   url(r'^myview/(?P<parameter_name>[A-Za-z0-9-_]+)/$',
       views.MyView(),
       name="myproject-myapp-myview",
       ),
)

【问题讨论】:

注意:以这种方式调用视图不是线程安全的。您应该为每个调用创建一个新实例。 能否请您给出该视图的 url 定义?? 【参考方案1】:

根据django docs:

要装饰基于类的视图的每个实例,您需要装饰 类定义本身。为此,您将装饰器应用于 类的 dispatch() 方法。

所以你需要做类似的事情:

class MyView(ApiView):

    def POST(self):
       # (...)
       return HttpResponse(json.dumps(True), mimetype="text/javascript")

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(MyView, self).dispatch(*args, **kwargs)

【讨论】:

由于海报在大写字母中使用 POST,我认为他没有使用基于 django 类的视图 @william- 很好。这个答案不适用。 是的,我没有使用基于 django 类的视图。我m very sorry that I missed that MyView is a callable, as ApiView implements __call__ (Im 维护别人的代码)。所以,这个类是一个可调用的,并且该类上的 @csrf_exempt 曾经在 django 1.2 中工作,但在 1.4 中没有。 这无论如何都行不通,即使对于基于类的视图也是如此。根据文档,您必须将 csrf_exempt 装饰器包装在 method_decorator 装饰器中:@method_decorator(csrf_exempt) 最后。感谢上帝。那是非常复杂的。感谢您提供实际有效的答案。【参考方案2】:

只需在urls.py 中使用csrf_exempt。即::

urls.py

​​>
..other imports...
from django.views.decorators.csrf import csrf_exempt   
from myapp.views import MyView

urlpatterns = patterns('',
   url(r'^myview/(?P<parameter_name>[A-Za-z0-9-_]+)/$',
       csrf_exempt(MyView.as_view()), # use csrf_exempt here
       name="myproject-myapp-myview",
       ),
)

【讨论】:

【参考方案3】:

csrf_exempt 必须装饰一个函数。在您的网址中,您可以装饰一个该功能,docs can be found here。

(r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),

【讨论】:

对不起,我没有注意到一个重要的事实:这个类是可调用的。我刚刚更新了问题。

以上是关于@csrf_exempt 在 Django 1.4 中停止工作的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 django-rest-framework 时不需要 `csrf_exempt`?

403 由石墨烯-django 提供。不要使用 csrf_exempt

django中form表单post无法提交

csrf_exempt装饰器在基于Dajngo函数的视图中不起作用

django若干问题

Django ajax post 403 问题