我正在关注用户注册的示例,我的代码看起来像这样
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.
有关我可能做错的任何建议吗?
答案 0 :(得分:2)
CSRF保护您的django网站有两种方式:
django.middleware.csrf.CsrfViewMiddleware
会自动将CSRF令牌添加到上下文中。
默认情况下,您的settings.py
文件会启用此中间件,您可以在模板中直接使用此令牌。
使用此解决方案,您无需做任何事情,只能使用模板中的{%csrf_token%}标记。
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的装饰器:
答案 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
装饰器来实际保护您的观看次数。