Saturday, 29 April 2017

django form usage and validations

django form usage and validations
Let's start with an example, If you are applying for a college admission you will fill up the college admission form with your details and submit it to the college.
It's general process for college admission. No web interactivity.

If we are applying for a college in web. We go to college website and we fill the details in a web form(HTML Form) and submit it.

In backend web application will store the data submitted by the student/user.
To avoid the data redundancy or invalid data we have to validated the form and show the errors to the user to take relevant information from the user.

Developer part:
To perform the above process developer has to write the html forms with hands. It consumes the time of developer. we can avoid writing of html forms with django forms.

Advantages of using the django forms

1. Automated HTML creation
2. Basic validation of data
3. Custom validations for fields
4. Automatic saving of data for model forms

Let's start using Django Forms

Use Case:  User Registration for web application

from django import forms
from app.models import User

class RegistrationForm(forms.Form):
    first_name = forms.CharField()
    last_name = forms.CharField()
    email = forms.EmailField()
    password = forms.CharField(widget=forms.HiddenInput())
    profile_pic = forms.ImageField()
    address = forms.CharField(widget=forms.Textarea())

    def clean_email(self):
        email = self.cleaned_data.get('email')
        # check and raise error if other user already exists with given email
        is_exists = User.objects.filter(email=email).exists()
        if is_exists:
            raise forms.ValidationError("User already exists with this email")
        return email
    def clean(self):
        data = self.cleaned_data
        # use your logic for non field errors
        return data

Django forms consists of three components.

1. Fields
2. Widgets
3. Custom Validators

  • It is responsible for basic validation of data
  • Every field has default validation logic and  a default widget.
  • It generates the HTML form elements with the help of widgets.
  • HTML form elements "input", "textarea", "select", "checkbox", "radio", etc.
  • Django Form Fields:
  • It is responsible for generation of HTML form elements.
  • we can write and use custom widgets
3. Custom Validators
  •  The Custom Validator allows us to create a validation control with customized validation logic.

Levels of validations in django forms

1. Basic Field Validation
2. Custom Field Validation
3. Non Fields Validation / Common Fields Validation  

1. Basic Field Validation
  • It is the first method to validate the data ("to_python")
  • Every field has a basic validation logic based on the type 
  • Example: "EmailField" has the logic to validate whether the given data is valid email or not.
2. Custom Field Validation
  • It is called after basic validation method "to_python".
  • It has method signature as "clean_<field name>"
  • Validation logic goes inside the method
3. Non Fields Validation / Common Fields Validation
  • It is called after the custom field validation method.
  • method signature is "clean"
  • we override it only if we need to validate multiple fields at the same time.

 Handling django forms

form = RegistrationForm(data={}, files={}, initial={})
django form class takes the three initial arguments "data", "files", "initial" if we provide it otherwise it takes it as empty.
data: form data
files: form files
initial: initial data to be rendered with widgets to show to the user.

Form usage in views

def register(request):
        create user & send one time activation email to user
    print(request.POST, request.FILES)
    # make sure to keep enctype="multipart/form-data" in html form
    if request.POST:
        form = RegistrationForm(request.POST, request.FILES)
        if form.is_valid():
            first_name = form.cleaned_data.get("first_name")
            last_name = form.cleaned_data.get("last_name")
            email = form.cleaned_data.get("email")
            profile_pic = form.cleaned_data.get("profile_pic")
            password = form.cleaned_data.get("password")
            user = User.objects.create(
            # send one time activation email
            # send_account_activation_email(request, user)
            return redirect('books_list')
        form = RegistrationForm()
    return render(request, 'registration.html', {'form': form})

form.cleaned_data => returns a dictionary with validated data
form.is_valid() => returns a boolean True if form data is valid otherwise False

Form usage in template

{% extends 'base.html' %}

{% block content %}
<div class="wrapper" style="color: blue; padding: 100px;">
        <form action="" enctype="multipart/form-data" method="POST">
            <legend> Registration </legend>
     {% csrf_token %}
     {{ form.as_p }}
     <input type="submit" value="submit" />
{% endblock %}

In the next blog post we will see sending one time use activation link email.