Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django, show ValidationError in template

Tags:

I create a registation app, where users can register providing a username, email and a password. What I did is make sure that the email field is unique(as you can see in the code below). But I can't figure out how I can show the error in case the a user enters an email address that is already in use.

View

from django.shortcuts import render from django.shortcuts import render_to_response from django.http import HttpResponseRedirect from django.core.context_processors import csrf  from forms import RegistrationForm  # Create your views here. def register_user(request):     if request.method == 'POST':         form = RegistrationForm(request.POST)         if form.is_valid():             form.save()             return HttpResponseRedirect('../../membership/register_success')         else:             return HttpResponseRedirect('../../membership/register_failed')      args = {}     args.update(csrf(request))      args['form'] = RegistrationForm()      return render(request,'registration/registration_form.html', args)  def register_success(request):     return render_to_response('registration/registration_success.html')  def register_failed(request):     return render_to_response('registration/registration_failed.html') 

Form

from django import forms from django.contrib.auth.models import User from django.contrib.auth.forms import UserCreationForm from django.utils.translation import ugettext_lazy as _      # forms.py     class RegistrationForm(UserCreationForm):         email = forms.EmailField(required=True)          class Meta:             model = User             fields = ('username', 'email', 'password1', 'password2')          def clean_email(self):             email = self.cleaned_data.get('email')             username = self.cleaned_data.get('username')              if email and User.objects.filter(email=email).exclude(username=username).count():                 raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))             return email          def save(self, commit=True):             user = super(RegistrationForm, self).save(commit=False)             user.email = self.cleaned_data['email']             if commit:                 user.save()             return user 

registration.html

    {% extends "base.html" %}     {% block title %}Registration{% endblock %}      {% block content %}              <h1>Registration</h1>              {% if form.errors %}             <h1>ERRORRRRRR same email again???</h1>             {% endif %}              {% if registered %}             <strong>thank you for registering!</strong>             <a href="../../">Return to the homepage.</a><br />             {% else %}             <strong>register here!</strong><br />              <form method="post" action="/membership/register/">{% csrf_token %}                 {{ form }}                 <input type="submit" name="submit" value="Register" />             </form>             {% endif %}      {% endblock %} 
like image 769
manosim Avatar asked Mar 18 '14 04:03

manosim


1 Answers

You're showing the form with {{ form }} on the template. That itself should show all the validation errors by default, but in your case, you're redirecting to some other page if the form is invalid. So you can never show the errors unless you pass the errors with the GET parameters. You could change your view to this to get the errors on the signup page itself -

def register_user(request):     args = {}     if request.method == 'POST':         form = RegistrationForm(request.POST)         if form.is_valid():             form.save()             return HttpResponseRedirect('../../membership/register_success')     else:         form = RegistrationForm()     args['form'] = form      return render(request,'registration/registration_form.html', args) 

How this works is, if the request method is POST, the form gets initiated with the POST data, then it's validated with the is_valid() call, so the form object now has the validation error messages if it's invalid. If it's valid, it's saved and redirected. If not valid, it comes to the args['form'] = form part where the form object with the error messages is set to the context and then passed to render.

If the request method is not POST, then a form object with no data is instantiated and passed to render().

Now your template should show all the error messages just below each field if there is any error.

like image 197
Bibhas Debnath Avatar answered Sep 22 '22 06:09

Bibhas Debnath