你能从请求对象构造csrf - csrf构造函数异常吗?

时间:2016-09-20 22:17:27

标签: python django

我正在关注用户注册的示例,我的代码看起来像这样

from django.views.decorators import  csrf
def register_user(request):
    args={}
    args.update(csrf(request)) #---->Crashes here
    args["form"] = UserCreationForm()
    return render_to_response("register.html",args)

我在声明中得到了一个例外

args.update(csrf(request))

说明

module object is not callable.

有关我可能做错的任何建议吗?

3 个答案:

答案 0 :(得分:2)

CSRF保护您的django网站有两种方式:

1 - 使用中间件,最简单的方法:

django.middleware.csrf.CsrfViewMiddleware会自动将CSRF令牌添加到上下文中。

默认情况下,您的settings.py文件会启用此中间件,您可以在模板中直接使用此令牌。

使用此解决方案,您无需做任何事情,只能使用模板中的{%csrf_token%}标记。

2 - 使用csrf_protect装饰器:

如果你停用中间件(不推荐使用),你仍然可以使用csrf_protect装饰器(看起来这是你正在尝试的解决方案,但不是Danielle指出的正确导入)。 / p>

但你的问题似乎是你不应该使用它。

它是一个装饰器,即一个返回作为参数传递的函数的修改版本的函数。在这里你传递一个请求对象。

使用Python,您可以这样使用装饰器:

@decorator
def function([...]):
    [...]

所以你的观点应该是这样的:

@csrf_token
def your_view(request, *args, **kwargs):
    # Your view code

使用{% csrf_token %}标记:

使用其中一种解决方案后,您可以直接在模板中使用{% csrf_token %}标记,因为csrf标记应该在模板渲染的上下文中(感谢中间件或csrf_protect装饰器) ):

<form>
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Submit" />
</form>

以下是有关Django的CSRF保护的更多信息:

https://docs.djangoproject.com/en/1.10/ref/csrf/

这里有更多关于使用Python的装饰器:

https://wiki.python.org/moin/PythonDecorators

答案 1 :(得分:1)

快速谷歌显示csrf装饰器的正确导入是

from django.views.decorators.csrf import csrf_protect

我的猜测(我没有可用于测试的django)是你正在导入别的东西,虽然它可能是一个不可调用的模块:)

答案 2 :(得分:1)

根据您的代码判断,您需要django.template.context_processors.csrf(),而不是django.views.decorators.csrf。这会将csrf标记放在模板上下文中。

推荐的方法是使用render代替render_to_response。这将运行所有已配置的context processors,包括csrf上下文处理器。

from django.shortcuts import render

def register_user(request):
    args = {}
    args["form"] = UserCreationForm()
    return render(request, "register.html", args)

这使您可以在模板中使用{% csrf_token %}模板标记。

您仍然需要使用CsrfViewMiddleware(推荐)或csrf_protect装饰器来实际保护您的观看次数。