Ich bin neu in Python. Auch neu bei Django. Ich versuche eine AJAX-Anfrage zu stellen und habe die Anweisungen hier. Zuerst war das Ergebnis des Abrufs des csrf-Cookies immer null, daher fand ich eine Dekorationsmethode namens sure_csrf_cookie. Das Problem ist, dass nach einer Ansicht gefragt wird und ich keine Ahnung habe, welche Ansicht übergeben werden soll und wo ich einen Verweis darauf erhalten kann. Der Code ist ganz einfach:

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!" })

Muss ich eine klassenbasierte Ansicht verwenden? Wenn ja, gibt es eine bessere Möglichkeit, den Cookie zu setzen? Ich möchte die hier beschriebene Methode nicht verwenden, da ich den Wert nicht manuell verarbeiten muss.

Der Rest des Codes lautet wie folgt:

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',
)
10
Nicolás Straub 21 Nov. 2013 im 17:56

4 Antworten

Beste Antwort

Cookies werden auf die Serverantwort gesetzt, daher müssen Sie @ensure_csrf_cookie decorator für die Ansicht einrichten, die die Seite rendert, von der aus der Benutzer eine Ajax-Anfrage stellt.

Wenn der Benutzerbrowser beispielsweise eine Ajax-Anfrage auf der Hauptseite der Site stellt, legen Sie diesen Dekorator für die Ansicht fest, der für die Hauptseite verantwortlich ist.

UPDATE: Ajax-Anforderungsaufrufe von der Sandbox-Seite? Versuchen Sie dann, sure_csrf_cookie für die Sandbox-Ansicht wie folgt festzulegen:

@ensure_csrf_cookie
def sandbox(request):
...
14
Nikita 21 Nov. 2013 im 14:21

CSRF-Token werden automatisch validiert, wenn Sie:

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

In Ihrer Projektdatei settings.py.

Wenn Sie über eine solche Middleware verfügen, müssen Sie nur die Variable crsf_token in alle Ihre Formulare (in Vorlagen) einfügen. Diese Variable wird automatisch überprüft, z. B.:

<form>
{% csrf_token %}
...

Ich weiß nicht, ob ich dein Problem überhaupt verstanden habe;)

2
marxin 21 Nov. 2013 im 14:01

Obwohl Sie gefunden haben, wonach Sie gesucht haben, helfen Ihnen diese Konzepte.

Ansichten sind Funktionen, die aufgerufen werden, wenn eine URL angefordert wird. Und es gibt zwei Arten von Ansichten:

  1. Funktionsbasierte Ansichten
  2. Klassenbasierte Ansichten.

Die grundlegende Arbeitsweise der Ansicht besteht darin, eine HTTP-Anforderung zu verarbeiten und eine HTTP-Antwort zu senden. Und jede Ansicht, die eine HttpResponse zurückgibt, muss einen Anforderungsparameter haben.

Aus einer funktionsbasierten Ansicht:

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

Ich sehe in Ihrer Ansicht keinen request Parameter.

Jetzt ist ein Dekorateur etwas, das bestimmte Bedingungen für eine Ansicht stellt.

Beispiel: Wenn Sie eine Ansichtsfunktion zum Kommentieren haben und möchten, dass der Benutzer zum Kommentieren angemeldet ist, können Sie einen login_required -Dekorator für die Ansicht verwenden.

Dadurch wird sichergestellt, dass sich jeder, der einen Kommentar abgeben möchte, zuerst anmelden muss. Die grundlegende Syntax lautet:

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

Ähnlich wie bei @login_required ist @ensure_csrf_cookie ein Dekorateur.

3
H H H 21 Nov. 2013 im 14:40

Für diejenigen, die nach einer Möglichkeit suchen, dies mit klassenbasierter Ansicht zu tun:

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):
       ...
12
Ryan Pergent 30 Apr. 2017 im 23:15