modelformset_factory and csrf token missing or incorrect

645 views Asked by At

I am using model formsets to add multiple instances of a model at once. and I am using class based views. This is my views.py part for creating a "Library"

class LibraryCreate(View):
model = Library

def post(self, request, *args, **kwargs):
    LibraryFormSet = modelformset_factory(
        Library, form=create_library, extra=2)
    if request.method == 'POST':
        formset = LibraryFormSet(request.POST, request.FILES)
        if formset.is_valid():
            # do something with the formset.cleaned_data
            pass
    else:
        formset = LibraryFormSet()
    return render_to_response(
        'trial1/library_form.html', {'formset': formset})

def get(self, request, *args, **kwargs):
    LibraryFormSet = modelformset_factory(
        Library, form=create_library, extra=2)
    formset = LibraryFormSet(queryset=Library.objects.none())
    return render_to_response(
        'trial1/library_form.html', {'formset': formset})

and this is my template

<form method="post" action="{% url "library_create" %}">
{% csrf_token %}
{{ formset.management_form }}
<table>
    {% for form in formset %}
    {{ form }}
    {% endfor %}
</table>
<input type="submit" value="create" />

now for some reason when I try to submit the form it returns a 403 forbidden because "CSRF token missing or incorrect.". I don't get why this is not working and its getting really frustrating.

2

There are 2 answers

2
Alasdair On

Use render instead of render_to_response so that the request is included in the template context.

return render(request, 'trial1/library_form.html', {'formset': formset})
0
Wouter Klein Heerenbrink On

You are missing the RequestContext object. The CSRF token is added by the CsrfMiddleware to the RequestContext object. When you do not include the object, the token will be empty (inspect the form element in your browser and you will see it is missing).

https://docs.djangoproject.com/en/1.8/ref/templates/api/#django.template.RequestContext

Use the render method or add the RequestContext to your view

 return render_to_response('trial1/library_form.html',
                          {'formset': formset},
                          context_instance=RequestContext(request))

https://docs.djangoproject.com/en/1.8/topics/http/shortcuts/#render https://docs.djangoproject.com/en/1.8/topics/http/shortcuts/#render-to-response (see context_instance attribute)