Reputation: 91999
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)
)
I even tried by adding {% csrf_token %}
, but no luck
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()**
Upvotes: 3
Views: 9019
Reputation: 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.
In views.py:
from django.template import RequestContext
...
...
...
return render_to_response("home.html", {}, context_instance=RequestContext(request))
Upvotes: -1
Reputation: 1217
add context_instance=RequestContext(request)
to every view that you will use a form inside it:
return render_to_response('index.html', {}, context_instance=RequestContext(request) )
return render_to_response('photos.html', {'photos': photos}, context_instance=RequestContext(request) )
Upvotes: 9
Reputation: 4635
Supposing you are using a fairly recent version of Django (1.3/1.4/dev) you should follow these steps :
settings.py
, Add the middleware django.middleware.csrf.CsrfViewMiddleware
to the
MIDDLEWARE_CLASSES
list.{% crsf_token %}
in the form.django.core.context_processors.csrf
context processor is used either by :
RequestContext
from django.template
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))
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)
(exhaustive post for posterity and future viewers)
Upvotes: 5
Reputation: 11102
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.
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
.
Upvotes: 3
Reputation: 4859
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.
http://lincolnloop.com/blog/2008/may/10/getting-requestcontext-your-templates/
Upvotes: 1
Reputation: 724
Try using the @csrf_protect decorator:
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})
Upvotes: 0
Reputation: 3964
Check in the settings, if you have this middleware:
'django.middleware.csrf.CsrfViewMiddleware'
https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
Upvotes: 2