8 min read

(For more resources related to this topic, see here.)

When displaying the form, it will generate the contents of the form template. We may change the type of field that the object sends to the template if needed.

While receiving the data, the object will check the contents of each form element. If there is an error, the object will send a clear error to the client. If there is no error, we are certain that the form data is correct.

CSRF protection

Cross-Site Request Forgery (CSRF) is an attack that targets a user who is loading a page that contains a malicious request. The malicious script uses the authentication of the victim to perform unwanted actions, such as changing data or access to sensitive data.

The following steps are executed during a CSRF attack:

  1. Script injection by the attacker.

  2. An HTTP query is performed to get a web page.

  3. Downloading the web page that contains the malicious script.

  4. Malicious script execution.

In this kind of attack, the hacker can also modify information that may be critical for the users of the website. Therefore, it is important for a web developer to know how to protect their site from this kind of attack, and Django will help with this.

To re-enable CSRF protection, we must edit the settings.py file and uncomment the following line:

'django.middleware.csrf.CsrfViewMiddleware',

This protection ensures that the data that has been sent is really sent from a specific property page. You can check this in two easy steps:

  1. When creating an HTML or Django form, we insert a CSRF token that will store the server. When the form is sent, the CSRF token will be sent too.

  2. When the server receives the request from the client, it will check the CSRF token. If it is valid, it validates the request.

Do not forget to add the CSRF token in all the forms of the site where protection is enabled. HTML forms are also involved, and the one we have just made does not include the token. For the previous form to work with CSRF protection, we need to add the following line in the form of tags and <form> </form>:

{% csrf_token %}

The view with a Django form

We will first write the view that contains the form because the template will display the form defined in the view. Django forms can be stored in other files as forms.py at the root of the project file. We include them directly in our view because the form will only be used on this page. Depending on the project, you must choose which architecture suits you best. We will create our view in the views/create_developer.py file with the following lines:

from django.shortcuts import render from django.http import HttpResponse from TasksManager.models import Supervisor, Developer from django import forms # This line imports the Django forms package class Form_inscription(forms.Form): # This line creates the form with four fields. It is an object that
inherits from forms.Form. It contains attributes that define the form fields. name = forms.CharField(label="Name", max_length=30) login = forms.CharField(label="Login", max_length=30) password = forms.CharField(label="Password", widget=forms.PasswordInput) supervisor = forms.ModelChoiceField(label="Supervisor",
queryset=Supervisor.objects.all()) # View for create_developer def page(request): if request.POST: form = Form_inscription(request.POST) # If the form has been posted, we create the variable that will
contain our form filled with data sent by POST form. if form.is_valid(): # This line checks that the data sent by the user is consistent
with the field that has been defined in the form. name = form.cleaned_data['name'] # This line is used to retrieve the value sent by the client.
The collected data is filtered by the clean() method that we will see later.
This way to recover data provides secure data. login = form.cleaned_data['login'] password = form.cleaned_data['password'] supervisor = form.cleaned_data['supervisor'] # In this line, the supervisor variable is of the Supervisor
type, that is to say that the returned data by the cleaned_data dictionary
will directly be a model. new_developer = Developer(name=name, login=login,
password=password, email="", supervisor=supervisor) new_developer.save() return HttpResponse("Developer added") else: return render(request, 'en/public/create_developer.html',
{'form' : form}) # To send forms to the template, just send it like any
other variable. We send it in case the form is not valid in order to
display user errors: else: form = Form_inscription() # In this case, the user does not yet display the form, it
instantiates with no data inside. return render(request, 'en/public/create_developer.html',
{'form' : form})

This screenshot shows the display of the form with the display of an error message:

Template of a Django form

We set the template for this view. The template will be much shorter:

{% extends "base.html" %} {% block title_html %} Create Developer {% endblock %} {% block h1 %} Create Developer {% endblock %} {% block article_content %} <form method="post" action="{% url "create_developer" %}" > {% csrf_token %} <!-- This line inserts a CSRF token. --> <table> {{ form.as_table }} <!-- This line displays lines of the form.--> </table> <p><input type="submit" value="Create" /></p> </form> {% endblock %}

As the complete form operation is in the view, the template simply executes the as_table() method to generate the HTML form.

The previous code displays data in tabular form. The three methods to generate an HTML form structure are as follows:

  • as_table: This displays fields in the <tr> <td> tags

  • as_ul: This displays the form fields in the <li> tags

  • as_p: This displays the form fields in the <p> tags

So, we quickly wrote a secure form with error handling and CSRF protection through Django forms.

The form based on a model

ModelForms are Django forms based on models. The fields of these forms are automatically generated from the model that we have defined. Indeed, developers are often required to create forms with fields that correspond to those in the database to a non-MVC website.

These particular forms have a save() method that will save the form data in a new record.

The supervisor creation form

To broach ModelForms, we will take, for example, the addition of a supervisor. For this, we will create a new page. For this, we will create the following URL:

url(r'^create-supervisor$', 'TasksManager.views.create_supervisor.page',
name="create_supervisor"),

Our view will contain the following code:

from django.shortcuts import render from TasksManager.models import Supervisor from django import forms from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse def page(request): if len(request.POST) > 0: form = Form_supervisor(request.POST) if form.is_valid(): form.save(commit=True) # If the form is valid, we store the data in a model record
in the form. return HttpResponseRedirect(reverse('public_index')) # This line is used to redirect to the specified URL. We use
the reverse() function to get the URL from its name defines urls.py. else: return render(request, 'en/public/create_supervisor.html',
{'form': form}) else: form = Form_supervisor() return render(request, 'en/public/create_supervisor.html',
{'form': form}) class Form_supervisor(forms.ModelForm): # Here we create a class that inherits from ModelForm. class Meta: # We extend the Meta class of the ModelForm. It is this class that
will allow us to define the properties of ModelForm. model = Supervisor # We define the model that should be based on the form. exclude = ('date_created', 'last_connexion', ) # We exclude certain fields of this form. It would also have
been possible to do the opposite. That is to say with the fields property,
we have defined the desired fields in the form.

As seen in the line exclude = (‘date_created’, ‘last_connexion’, ), it is possible to restrict the form fields. Both the exclude and fields properties must be used correctly. Indeed, these properties receive a tuple of the fields to exclude or include as arguments. They can be described as follows:

  • exclude: This is used in the case of an accessible form by the administrator. Because, if you add a field in the model, it will be included in the form.

  • fields: This is used in cases in which the form is accessible to users. Indeed, if we add a field in the model, it will not be visible to the user.

For example, we have a website selling royalty-free images with a registration form based on ModelForm. The administrator adds a credit field in the extended model of the user. If the developer has used an exclude property in some of the fields and did not add credits, the user will be able to take as many credits as he/she wants.

We will resume our previous template, where we will change the URL present in the attribute action of the <form> tag:

{% url "create_supervisor" %}

This example shows us that ModelForms can save a lot of time in development by having a form that can be customized (by modifying the validation, for example).

Summary

This article discusses Django forms. It explains how to create forms with Django and how to treat them.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here