Django: проверка CSRF не удалась даже после добавления {% csrf_token%} - PullRequest
3 голосов
/ 07 декабря 2011

views.py:

def index(request):
    return render_to_response('index.html', {})

def photos(request, artist):
    if not artist:
        return render_to_response('photos.html', {'error' : 'no artist supplied'})
    photos = get_photos_for_artist(artist)
    if not photos:
        logging.error('Issue while getting photos for artist')
        return render_to_response('photos.html', {'error': 'no matching artist found'})
    return render_to_response('photos.html', {'photos': photos})  

Index.html:

<html>
    <head>
        <title>find artist photos </title>
    </head>
    <body>
        {% block error %} {% endblock %}
        <form action="/photos" method="POST">
            {% csrf_token %}
            <label for="artist">Artist : </label>
            <input type="text" name="artist">
            <input type="submit" value="Search">
        </form>
        {% block content %}{% endblock %}
    </body>
</html>

photos.html:

{% extends 'index.html' %}
{% block error %}
    {% if error %}
        <p> {{ error}} </p>
    {% endif %}
{% endblock %}

{% block content %}
    {% if photos %}
        {% for photo in photos %}
            {{ photo }}
        {% endfor %}
    {% endif %}
{% endblock%}

url.py:

urlpatterns = patterns('',
    (r'', index),
    (r'^time/$', current_datetime),
    (r'^photos/(\w+)$', photos)
)

Я даже пытался добавить {% csrf_token %}, но не повезло

Спасибо

UPDATE
Я вижу это в журналах

UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value.  This is usually caused by not using RequestContext.
  warnings.warn("A {% csrf_token %} was used in a template, but the context did not provide the value.  This is usually caused by not using RequestContext.")  

Это произошло после добавления context_instance = RequestContext (request) ** к render_to_response () **

Ответы [ 7 ]

9 голосов
/ 07 декабря 2011

добавить context_instance=RequestContext(request) к каждому представлению, что вы будете использовать форму внутри него:

return render_to_response('index.html', {}, context_instance=RequestContext(request) )


return render_to_response('photos.html', {'photos': photos}, context_instance=RequestContext(request) )
5 голосов
/ 26 июля 2012

Предполагая, что вы используете довольно свежую версию Django (1.3 / 1.4 / dev), вы должны выполнить следующие шаги:

  • В settings.py, добавьте промежуточное ПО django.middleware.csrf.CsrfViewMiddleware к MIDDLEWARE_CLASSES список.
  • В вашем шаблоне используйте {% crsf_token %} в форме.
  • По вашему мнению, убедитесь, что контекстный процессор django.core.context_processors.csrf используется либо:
    • использовать RequestContext от django.template
    • напрямую импортирует процессор csrf из from django.core.context_processors

Примеры

from django.template import RequestContext
from django.shortcuts import render_to_response

def my_view(request):
    return render_to_response('my_template.html', {}, context_instance=RequestContext(request))

или

from django.core.context_processors import csrf
from django.shortcuts import render_to_response

def my_view(request):
    c = {csrf(request)}
    return render_to_response('my_template.html', c)

Ссылки

(исчерпывающий пост для потомков и будущих зрителей)

3 голосов
/ 08 декабря 2011

Здесь есть несколько проблем:

  • Пожалуйста, загрузите свою «индексную» страницу в веб-браузере, выполните «Просмотр источника» и проверьте, расширяется ли {% csrf_token %}. Его следует заменить на тег <input>. Если этого не происходит, значит, у вас проблемы с индексной страницей. Если он заменяется правильно, у вас есть проблемы со страницей ваших фотографий.

  • URL-адрес POST в index.html не соответствует ни одному из шаблонов в urls.py. Ваш urls.py, похоже, ожидает, что поисковый термин будет частью URL, но это не так - вы отправляете его как параметр HTTP POST. Вам нужно получить к нему доступ через request.POST.

2 голосов
/ 07 декабря 2011

Проверьте в настройках, если у вас есть это промежуточное ПО:

'django.middleware.csrf.CsrfViewMiddleware'

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

1 голос
/ 07 декабря 2011

Вам может понадобиться явно передать экземпляр RequestContext при использовании render_to_response, чтобы получить значения CSRF для этого тега шаблона.

http://lincolnloop.com/blog/2008/may/10/getting-requestcontext-your-templates/

0 голосов
/ 21 февраля 2017

Это сработало для меня:

{% csrf_token%} В шаблоне есть тег шаблона {% csrf_token%} внутри каждой формы POST, предназначенный для внутреннего URL.

В views.py:

из django.template import RequestContext

...

...

...

return render_to_response ("home.html", {}, context_instance = RequestContext (request) )

0 голосов
/ 07 декабря 2011

Попробуйте использовать декоратор @csrf_protect:

from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render_to_response

@csrf_protect
def photos(request,artist):
    if not artist:
        return render_to_response('photos.html', {'error' : 'no artist supplied'})
    photos = get_photos_for_artist(artist)
    if not photos:
        logging.error('Issue while getting photos for artist')
        return render_to_response('photos.html', {'error': 'no matching artist found'})
    return render_to_response('photos.html', {'photos': photos})  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...