2013-11-21 68 views
6

我是python新手。 Django也是新的。我試圖發出AJAX請求並按照說明here。起初,檢索csrf cookie的結果始終爲空,因此我找到了一個名爲ensure_csrf_cookie的裝飾器方法。問題是它需要一個視圖,我不知道要傳遞什麼視圖以及我可以在哪裏獲得參考。代碼很簡單:我該如何使用ensure_csrf_cookie?

from django.shortcuts import render_to_response 
from django.core.context_processors import csrf 
from django.views.decorators.csrf import ensure_csrf_cookie 

def csv_to_xform(csv, template): 
    return render_to_response(template, { "data": "it works!" }) 

我需要使用基於類的視圖嗎?如果是這樣,是否有更好的方法來設置Cookie?我不想使用描述here的方法,因爲我不想手動處理值。

的代碼的其餘部分是如下:

sandbox.html:

<!doctype html> 

<html> 
    <head> 
     <title>Sandbox</title> 

     <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> 
     <script src="/static/js/csrf.js"></script> 

     <script type="text/javascript"> 
      $(function() { 
       $('#send-csv-btn').click(function() { 
        $.post('/csv', { 
         data: '1, 2, 3', 
         success: function (response) { 
          console.debug(response); 
         }, 
         error: function (response) { 
          console.debug(response); 
         } 
        }); 
       }); 
      }); 
     </script> 
    </head> 

    <body> 
     <form> 
      {% csrf_token %} 
      <input type="button" id="send-csv-btn" /> 
     </form> 
    </body> 
</html> 

urls.py:

urlpatterns = patterns('', 
    url(r'^$', 'dkobo.formbuilder.views.main', name='fb'), 
    url(r'^admin/', include(admin.site.urls)), 
    url(r'^csv$', 'dkobo.formbuilder.views.csv_to_xform', { "template": "sandbox-stub.html" }), 
    url(r'^sandbox$', 'dkobo.formbuilder.views.sandbox') 
) 

settings.py:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    'django.middleware.clickjacking.XFrameOptionsMiddleware', 
) 

回答

11

餅乾在服務器響應設置,所以你需要設置@ensure_csrf_cookie裝飾視圖,呈現頁面,從哪個用戶將發出ajax請求。

例如,如果用戶瀏覽器在網站主頁上做出ajax-request,則將該裝飾器設置爲view,負責主頁面。

更新: ajax請求來自沙箱頁面的呼叫? 再試着設置爲ensure_csrf_cookie沙箱視圖,就像這樣:

@ensure_csrf_cookie 
def sandbox(request): 
... 
+0

我上傳了其餘的代碼......你能舉個例子嗎? –

+0

我更新了回答 – Nikita

+0

很好,它的工作!謝謝。 –

3

CSRF令牌自動驗證你有:

MIDDLEWARE_CLASSES = (
... 
'django.middleware.csrf.CsrfViewMiddleware', 
... 
) 

在你的項目settings.py文件。

當你有這樣的中間件,你只需要投入crsf_token變量所有的表格(模板),並且它會自動驗證,例如:

<form> 
{% csrf_token %} 
... 

我不知道如果我理解你的問題在所有;)

+0

根據我的理解,在'{%csrf_token%}'元素必須是一個表單中。我的模板上可能沒有表單(在這種情況下,我可以,但它是沙箱)。我基本上希望能夠在沒有表單元素的情況下設置cookie –

+0

我嘗試了你說的,並且它不起作用。 「{%csrf_token%}」不會返回任何內容。我正在更新帖子以包含其他相關代碼。 –

3

雖然你發現你正在尋找這些概念會幫助你。

視圖是在請求URL時被調用的函數。有兩種類型的視圖:基於

  1. 功能的觀點基於
  2. 類的觀點。

視圖的基本工作是處理一個HttpRequest併發出一個HttpResponse。 而且每個返回HttpResponse的視圖都必須有一個請求參數。

防爆功能基於視圖:

def myView(request): 
    ... 
    # process the request here 
    return HttpResponse() # or render_to_response depending upon what you want. 

我沒有看到在你看來一個request參數。

現在裝飾器是在視圖上放置某些條件的東西。

例如:如果您有評論的查看功能,並且您希望用戶登錄進行評論,那麼您可以在視圖上使用login_required裝飾器。

這將確保任何想要評論的人首先需要登錄。基本語法是:

@login_required # this is the decorator 
def comment(request): # this is the view on which the decorator is acting upon 
... 
... 
return HttpResponse() 

到@login_required類似,@ensure_csrf_cookie是一個裝飾。

+0

aahhh現在我明白了!我知道關於視圖的部分,只是發現傳遞的第一個參數是請求對象。我不知道裝飾者與正常功能不同。感謝您解決這個問題! –

+0

我很高興.... –

+0

我在哪裏把它放在基於類的視圖上?例如DRF的「HyperLinkedModelViewSet」? – Jayen

9

對於那些正在尋找一種方式與基於類視圖做到這一點:

from django.utils.decorators import method_decorator 
from django.views.decorators.csrf import ensure_csrf_cookie 

class MyView(View): 

    @method_decorator(ensure_csrf_cookie) 
    def get(self, request, *args, **kwargs): 
     ...