Why does Django show this error: 'Forbidden (403)CSRF verification failed. Request aborted.' when I already have {% csrf_token %} in the form.
templates/core/signup.html
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Sign up</button>
</form>
{% endblock %}
views.py
from django.contrib.auth.forms import UserCreationForm
from django.views.generic.edit import CreateView
class SignUpView(CreateView):
template_name = 'core/signup.html'
form_class = UserCreationForm
Since you are already passing on the csrf token from django.core.context_processors.csrf to the context manager. Check whether the form HTML has something like this or not:
<input type='hidden' name='csrfmiddlewaretoken' value="jqhdwjavwjagjzbefjwdjqlkkop2j3ofje" />
A couple of other things are required to make the csrf protection work (check out the docs):
Your browser has to accept cookies from your server
Make sure you have 'django.middleware.csrf.CsrfViewMiddleware' included as middleware in your settings.py (alternatively use the decorator csrf_protect() on particular views you want to protect)
In your views.py you need to pass the RequestContext in your render_to_response for the context processors to actually be run.
from django.template import RequestContext
context = {}
return render_to_response('my_template.html',
context,
context_instance=RequestContext(request))
the new render shortcut (django 1.3+) will do it for you:
from django.shortcuts import render
context = {}
return render(request, 'my_template.html', context)
For class-based view:
class MyFormView(View):
form_class = MyForm
initial = {'key': 'value'}
template_name = 'form_template.html'
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
# <process form cleaned data>
return HttpResponseRedirect('/success/')
return render(request, self.template_name, {'form': form})
Related
im making a signup page in a django project using the UserCreationForm but when rendering my html i only see the submit button
from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm
def register(request):
form = UserCreationForm
return(render(request, 'register.html', {form: form}))
{% extends 'base.html' %}
{% block title %}Sign Up{% endblock %}
{% block body %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="button">
<button type="submit">Sign up</button>
</form>
{% endblock %}
You can not use the form as key of the context, you should use 'form'. Furthermore it is not a good idea to pass a reference to the class, you should create an instance of the form in the view, so:
from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm
def register(request):
form = UserCreationForm()
# use 'form' instead of form ↓ ↓
return render(request, 'register.html', {'form': form})
If you had used a form object, instead of a reference to the class, it would have raised an error that a Form is not hashable. But since you used a reference to the form class, there was no error, and thus this remained undetected.
The problem is within the django views function..Use below code instead..
you should pass it as a string variable {'form' :form}
return render(request, 'register.html', {'form': form})
I am trying to send a form to html using django. this is the form
from django import forms
class contactForm(forms.Form):
name = forms.CharField(required=False, max_length=100,help_text='100 characters max.')
email = forms.EmailField(required=True)
comment = forms.CharField(required=True, widget=forms.Textarea)
The view file is
from django.shortcuts import render
from .forms import contactForm
# Create your views here.
def contact(request):
form = contactForm(request.POST or None)
if form.is_valid():
print (request.POST)
context = locals()
template = 'contact.html'
return render(request, template, context)
and the html file which is named correctly is,
{% extends 'base.html' %}
{% block content %}
<h1> Contact </h1>
<form method='POST' action=''> {% csrf_token %}
{{ form.as_p }}
<input type='submit' value='submit form' class='btn btn-default' />
</form>
{% endblock %}
When you visit the page the only thing that shows up is the h1 tag how do i fix this?
You can try
def contact(request):
form = contactForm(request.POST or None)
if form.is_valid():
print (request.POST)
context = locals()
template = 'contact.html'
return render(request, template, context)
return render(request, 'contact.html', {'form': form})
The correct format of rendering a from is this:
from django.shortcuts import reverse
from django.http import HttpResponseRedirect
from . import models
from . import forms
def contact(request):
if request.POST == 'POST':
form = forms.contactForm(request.POST or None)
contact_model = models.contactModel() #err is here name it with appropriate model name contactModel is just an example
if form.is_valid():
contact_model.name = form.cleaned_data['name']
contact_model.email = form.cleaned_data['email']
contact_model.comment = form.cleaned_data['comment']
contact_model.save()
return HttpResponseRedirect('/success/')) #desired url to redirect, you can use reverse to call templates according to url names
else: #if request is GET
form = forms.contactForm()
context = {
'form': form
}
template = 'contact.html'
return render(request, template, context=context)
Do not use action in your template, just set your urls.py to redirect to the desired view.
only my Submit button is popping up when i am trying to pass a form.
I even tried just copying the code from the Django website... Still does not work for me.
This is my forms.py
from django import forms
class contactForm(forms.Form):
name = forms.CharField(required=False, max_length=100, help_text='100 max.')
email = forms.EmailField(required=True)
comment = forms.CharField(required=True, widget=forms.Textarea)
This is my views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from .forms import contactForm
def contact(request):
form = contactForm(request.POST or None)
if form.is_valid():
print(request.POST)
context = locals()
return render(request, 'contact/contact.html', context)
def index(request):
return render(request, 'contact/contact.html')
This is my contact.html
{% extends "contact/base.html" %}
{% block content %}
<h1>Contact</h1>
<form method='POST' acion=''> {% csrf_token %}
{{ form.as_p }}
<input type='submit' value='submit form'/>
</form>
{% endblock %}
I really do not know what is wrong with this code...please help! Thanks
ps: I am new to python, maybe i need another version?
You have two views rendering the same template. One of them, contact, passes the form to the template. The other, index, does not, so there is nothing called form in the context and the result will be blank.
I am beginner to python Django. And trying build an posting article website with the help of tutorials. I got stuck at UserCreationForm. I have created a form using UserCreationForm, but when I am submitting the form I am not able to neither submit the form nor getting any error message on the page.
My views.py code
from django.shortcuts import render_to_response
from django.contrib.auth import authenticate
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.template.context_processors import csrf
from django.contrib.auth.forms import UserCreationForm
def register_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
args = {}
args.update(csrf(request))
args['form'] = UserCreationForm()
print args
return render_to_response('register.html', args)
def register_success(request):
return render_to_response('register_success.html')
register.html
{% extends "base.html" %}
{% block content %}
<h2>Register</h2>
<form action="/accounts/register/" method="post"> {% csrf_token %}
{{form}}
<input type="submit" value="Register"/>
</form>
{% endblock %}
register_success.html
{% extends "base.hml" %}
{% block content %}
<h2>You have registered!</h2>
<p>Click Here to login again</p>
{% endblock %}
The problem is that you are always creating a blank form.
args['form'] = UserCreationForm()
This means that you do not see any errors for POST requests when the form is invalid.
Instead, you should only create the blank form for GET requests.
from django.shortcuts import render
def register_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
else:
form = UserCreationForm()
args = {'form': form}
return render(request, 'register.html', args)
Note that I have simplified the view by using render instead of the obsolete render_to_response. That means you don't need to handle csrf manually.
You can use Django Generic Views, specifically CreateView, it will make your life a lot easier. You can use it like so:
from django.views.generic import CreateView
class CreateUserView(CreateView):
template_name = 'register.html'
form_class = UserCreationForm
success_url = '/accounts/register_success'
Add this to your urls.py and you are good to go:
from mysite.views import CreateUserView
# add this url pattern
url(r'^sign_up/$', CreateUserView.as_view(), name='signup'),
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.
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})
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)