The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

koitaki (2) [Avatar] Offline
#1
With the Todo's application, when I went to add a new todo, I got this error:
CSRF verification failed. Request aborted.

It doesn't give much info on how to correct it.
The majority of advice given on StackOverflow suggested adding:
• {% csrf_token %} between the form tags
• context_instance=RequestContext(request)) as the 2nd argument in the render_to_response function.

However, with respect to the latter point, the book code doesn't use render_to_response, but uses instead HttpResponseRedirect(reverse(todo_index)), which doesn't seem to want to take the context_instance piece as a 2nd argument.

I've tried changing to the render_to_response function but no joy there either.

After a good while trying to find a solution, I've come here to seek advice for how to solve it. I've put the allegedly offending code below. Any suggestions?

Many thanks in advance!

def add_todo(request):
t = Todo(
title = request.POST['title'],
description = request.POST['description'],
importance = request.POST['importance'])
t.save()
# return HttpResponseRedirect(reverse(todo_index))
return render_to_response('index.tmpl',{'title': title, 'description': description, 'importance': importance},
context_instance=RequestContext(request))
koitaki (2) [Avatar] Offline
#2
Re: Chapter 8 Django CSRF Error (Listing 8.17)
Ok, after a fair bit of stumbling around, I've managed to no longer get the CSRF error. Next issue is that now I can't get any new Todo's to save. There are no warning messages, the runserver cmd screen shows a POST method, but nothing gets added to the database.

My current code for what I believe are the two relevant views:

def todo_index(request):
todos = Todo.objects.all().order_by('importance', 'title')
t = loader.get_template('index.tmpl')
c = Context({
'todos': todos,
'choices': importance_choices,
})
cs = {}
cs.update(csrf(c))
return render_to_response('index.tmpl', c, context_instance=RequestContext(request))

def add_todo(request):
t = Todo(
title = request.POST['title'],
description = request.POST['description'],
importance = request.POST['importance'])
t.save()
return HttpResponseRedirect(reverse(todo_index))

Any comments?
343340 (2) [Avatar] Offline
#3
I also had a CSRF Error when I attempted listing 8.16.

Following the instructions on the error page, I added a csrf token to index.tmpl:
<p>Add a todo:<br>
<form action="add" method="POST">{% csrf_token %}
	Todo:<input type="text" name="title"><br>
...

I also changed the Context in my index view to a RequestContext in views.py
def todo_index(request):
    todos = Todo.objects.all().order_by(
            'importance', 'title')
    t = loader.get_template('index.tmpl')
    c = RequestContext({'todos': todos,
                 'choices': importance_choices,
                 })
    return HttpResponse(t.render(c))

but that didn't work and I got a strange error that a "dict has no meta".
I tried many things, but finally read the Django documentation about the RequestContext https://docs.djangoproject.com/en/1.8/ref/templates/api/#subclassing-context-requestcontext and realized that the signature was different. One must pass the request object as well. This worked better:
 c = RequestContext(request, {'todos': todos,
                 'choices': importance_choices,
                 })


I had some other issues with my urls, but I think this is all that relates to the CSRF error.
343340 (2) [Avatar] Offline
#4
Re: Chapter 8 Django CSRF Error (Listing 8.17)
koitaki wrote:Ok, after a fair bit of stumbling around, I've managed to no longer get the CSRF error. Next issue is that now I can't get any new Todo's to save. There are no warning messages, the runserver cmd screen shows a POST method, but nothing gets added to the database.


That happened to me, too! After much blundering around, I found that changing the original project-level urls.py from the version given in listing 8.10 (I had just replaced todo.views.hello_world with the include)
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^.*', include(todo_urls)),  
] 

to the version in listing 8.15 (putting 'todos/' in the url string)
from todoApp import urls as todo_urls

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^todos/', include(todo_urls)),
]

magically solved the problem, though I don't know why.
RomanticStrings (3) [Avatar] Offline
#5
These solutions are not working for my app, which is being produced in Python 3.5.2/Django 1.10.1. I had to modify the entire procedure based upon the tutorial given on the Django Project page, since things have obviously changed since the book was produced. However, I fear that I have missed Hello! Python-specific details that don't match the tutorial page's project. Anyone had any success producing an updated project?
RomanticStrings (3) [Avatar] Offline
#6
I managed to solve the issue by changing my todo_index view to the following:

...
from django.template.loader import render_to_string
...
def todo_index(request):
    todos = Todo.objects.all().order_by(
        'importance', 'title')
    c = {'todos': todos,
         'choices': importance_choices}
    rendered = render_to_string('index.tmpl', c, request)
    return HttpResponse(rendered)