2016-09-20 183 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