Django:即使添加了{%csrf_token%},CSRF验证也失败了

时间:2021-08-31 06:39:01

views.py:

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:

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:

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:

url.py:

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

I even tried by adding {% csrf_token %}, but no luck

我甚至尝试添加{%csrf_token%},但没有运气

Thank you

谢谢

UPDATE
I see these in the logs

更新我在日志中看到了这些

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.")  

This came after adding context_instance=RequestContext(request) **to render_to_response()**

将context_instance = RequestContext(request)**添加到render_to_response()**之后

7 个解决方案

#1


9  

add context_instance=RequestContext(request) to every view that you will use a form inside it:

将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) )

#2


5  

Supposing you are using a fairly recent version of Django (1.3/1.4/dev) you should follow these steps :

假设您使用的是相当新版本的Django(1.3 / 1.4 / dev),您应该按照以下步骤操作:

  • In settings.py, Add the middleware django.middleware.csrf.CsrfViewMiddleware to the MIDDLEWARE_CLASSES list.
  • 在settings.py中,将中间件django.middleware.csrf.CsrfViewMiddleware添加到MIDDLEWARE_CLASSES列表中。
  • In your template, use the {% crsf_token %} in the form.
  • 在模板中,使用表单中的{%crsf_token%}。
  • In your view, ensure that the django.core.context_processors.csrf context processor is used either by :
    • use RequestContext from django.template
    • 使用来自django.template的RequestContext
    • directly import the csrf processor from from django.core.context_processors
    • 直接从django.core.context_processors导入csrf处理器
  • 在您的视图中,确保通过以下方式使用django.core.context_processors.csrf上下文处理器:使用来自django.template的RequestContext直接从django.core.context_processors导入csrf处理器

Examples

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))

or

要么

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)

References

(exhaustive post for posterity and future viewers)

(后人和未来观众的详尽帖子)

#3


3  

A number of things to troubleshoot here:

要解决的一些问题:

  • Please load your "index" page in a web browser, do "View Source", and check if the {% csrf_token %} is being expanded. It should be replaced with an <input> tag. If that's not happening, then you have problems with your index page. If it is being replaced correctly, then you have problems with your photos page.

    请在网络浏览器中加载“索引”页面,执行“查看源代码”,然后检查是否正在展开{%csrf_token%}。它应该替换为标签。如果没有发生这种情况,那么您的索引页面就会出现问题。如果正确更换,则说明您的照片页面有问题。

  • The POST URL in index.html doesn't match any of the patterns in urls.py. Your urls.py seems to expect the search term to be part of the URL, but it's not - you're sending it as a HTTP POST parameter. You need to access it via request.POST.

    index.html中的POST URL与urls.py中的任何模式都不匹配。您的urls.py似乎希望搜索字词是URL的一部分,但它不是 - 您将其作为HTTP POST参数发送。您需要通过request.POST访问它。

#4


2  

Check in the settings, if you have this middleware:

如果您有此中间件,请检查设置:

'django.middleware.csrf.CsrfViewMiddleware'

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

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

#5


1  

You may need to explicitly pass in a RequestContext instance when you use render_to_response in order to get the CSRF values for that template tag.

使用render_to_response时,可能需要显式传入RequestContext实例,以获取该模板标记的CSRF值。

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

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

#6


0  

Try using the @csrf_protect decorator:

尝试使用@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})  

#7


-1  

This worked for me:

这对我有用:

{% csrf_token %} In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.

{%csrf_token%}在模板中,每个POST表单中都有一个{%csrf_token%}模板标记,用于定位内部URL。

In views.py:

在views.py中:

from django.template import RequestContext

来自django.template导入RequestContext

...

...

...

...

...

...

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

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

#1


9  

add context_instance=RequestContext(request) to every view that you will use a form inside it:

将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) )

#2


5  

Supposing you are using a fairly recent version of Django (1.3/1.4/dev) you should follow these steps :

假设您使用的是相当新版本的Django(1.3 / 1.4 / dev),您应该按照以下步骤操作:

  • In settings.py, Add the middleware django.middleware.csrf.CsrfViewMiddleware to the MIDDLEWARE_CLASSES list.
  • 在settings.py中,将中间件django.middleware.csrf.CsrfViewMiddleware添加到MIDDLEWARE_CLASSES列表中。
  • In your template, use the {% crsf_token %} in the form.
  • 在模板中,使用表单中的{%crsf_token%}。
  • In your view, ensure that the django.core.context_processors.csrf context processor is used either by :
    • use RequestContext from django.template
    • 使用来自django.template的RequestContext
    • directly import the csrf processor from from django.core.context_processors
    • 直接从django.core.context_processors导入csrf处理器
  • 在您的视图中,确保通过以下方式使用django.core.context_processors.csrf上下文处理器:使用来自django.template的RequestContext直接从django.core.context_processors导入csrf处理器

Examples

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))

or

要么

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)

References

(exhaustive post for posterity and future viewers)

(后人和未来观众的详尽帖子)

#3


3  

A number of things to troubleshoot here:

要解决的一些问题:

  • Please load your "index" page in a web browser, do "View Source", and check if the {% csrf_token %} is being expanded. It should be replaced with an <input> tag. If that's not happening, then you have problems with your index page. If it is being replaced correctly, then you have problems with your photos page.

    请在网络浏览器中加载“索引”页面,执行“查看源代码”,然后检查是否正在展开{%csrf_token%}。它应该替换为标签。如果没有发生这种情况,那么您的索引页面就会出现问题。如果正确更换,则说明您的照片页面有问题。

  • The POST URL in index.html doesn't match any of the patterns in urls.py. Your urls.py seems to expect the search term to be part of the URL, but it's not - you're sending it as a HTTP POST parameter. You need to access it via request.POST.

    index.html中的POST URL与urls.py中的任何模式都不匹配。您的urls.py似乎希望搜索字词是URL的一部分,但它不是 - 您将其作为HTTP POST参数发送。您需要通过request.POST访问它。

#4


2  

Check in the settings, if you have this middleware:

如果您有此中间件,请检查设置:

'django.middleware.csrf.CsrfViewMiddleware'

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

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

#5


1  

You may need to explicitly pass in a RequestContext instance when you use render_to_response in order to get the CSRF values for that template tag.

使用render_to_response时,可能需要显式传入RequestContext实例,以获取该模板标记的CSRF值。

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

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

#6


0  

Try using the @csrf_protect decorator:

尝试使用@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})  

#7


-1  

This worked for me:

这对我有用:

{% csrf_token %} In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.

{%csrf_token%}在模板中,每个POST表单中都有一个{%csrf_token%}模板标记,用于定位内部URL。

In views.py:

在views.py中:

from django.template import RequestContext

来自django.template导入RequestContext

...

...

...

...

...

...

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

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