2016-09-20 195 views
0

我下面用户注册的例子,我的代码看起来像这样你可以从请求对象 - csrf构造函数异常构造csrf吗?

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. 

任何的建议我可能做错了什么?

回答

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修饰符才能真正保护您的视图。

1

快速谷歌显示,对于CSRF装饰正确导入

from django.views.decorators.csrf import csrf_protect 

我的猜测(我没有可测试的Django)是你别的东西进口,但它可能是一个非可调用模块:)

+0

不幸的是,这给了我相同的错误 –

+1

我认为你不正确地使用装饰 - 检查这里的文档为例:https://docs.djangoproject.com/en/1.10/ref/csrf/#module- django.views.decorators.csrf –

2

有两种方式来保护CSRF你的Django网站:

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

django.middleware.csrf.CsrfViewMiddleware会自动为上下文添加一个CSRF令牌。

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

使用此解决方案,您无需执行任何操作,只需在模板中使用{%csrf_token%}标记即可。

2 - 使用csrf_protect装饰:

如果禁用了中间件(不推荐),你仍然可以使用csrf_protect装饰(似乎这是你想要的解决方案,而不是与它正如Danielle指出的那样正确导入)。

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

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

使用Python,canuse一个装饰这样:

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

所以你的观点应该是这样的:使用{% csrf_token %}标签

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

使用这些解决方案之一后,您可以直接在模板中使用{% csrf_token %}标签,因为csrf标记应该位于模板呈现的上下文中(感谢middl eware或csrf_protect装饰):

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

这里有更多关于CSRF保护和Django:

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

这里更多的是装饰用的Python:

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

+0

我需要将我的视图中的CSRF值传递给我的模板吗? –

+0

不,你只需要'django.middleware.csrf.CsrfViewMiddleware'中间件(默认启用), – vmonteco

+0

@JamesFranco为了简化。你可以使用装饰器。但是,您可以直接在模板中使用此标记,而无需在视图中添加任何内容(假设您没有从'settings.py'中移除中间件)。 – vmonteco