Forms
The majority of web applications need to collect data from end-users. This can be anything from user details for login and authentication, registration details for a new application or order details for online shopping.
Recall that web applications use forums to collect data input from users using HTML form tags. Any form elements such as inputs are checkboxes, are sent to the server for processing when the form is submitted.
In Django, the most common form submission is a post request, which will send the data down in the post body. The server-side code handles the incoming request and processes the data on the backend.
For example, suppose you create a basic form using HTML to submit a name, you can use a label to display text describing what the inputs should have. The input set to type text accepts input from the end-user.
In this example, the inputs stores their name. The second input of type submit is a button that displays the text send name. When the button is pressed, the action will be triggered to make a post request to be processed by the order view.
This is all defined in the form action and form method attributes.
While this process works well, code can become tedious and complex when dealing with large forms. For example, forums can have many different ways of gathering data with conditional flows. Also, designing forms in this way can lead to errors as each form element’s name or ID attribute needs to match what the back-end code expects.
To assist developers with form creation and processing, Django uses a form class. In this class, you can define all the expected attributes that will be passed down in the request.
This means that you can use a form class to represent the expected attributes and render the form elements in the HTML.
Example
The submit name form can be represented by creating a class.
- First, you create a class called
NameForm
, which accepts a parameter of forms dot form. - Next, you create a variable called your name, which is assigned forms dot CharField to represent the HTML input element. Notice that you also can set some validation by setting the max length value to 100.
- Finally, When the name form class is rendered, it’s rendered to a view containing the HTML form code.
NOTE
It’s important to know that the form tags are not represented. You need to add the form tags and then use the templating to append the form elements inside.
For developers, the advantage of creating forms in this way makes it much easier to manage any changes to the form. Instead of worrying about the names on inputs matching with the server-side code, this is handled entirely by the forum class.
Also because you are working with classes, you get all the benefits of object oriented programming. For example, you can split complex forms into subclasses to make them more manageable.
Use of forms with models
Sending data to the back-end using the post method requires you to persist the data somehow. For example, suppose you are setting up a new user to gain access to your site, you will need to persist their details such as email and password and some general user information such as name or address.
Locally, developers can solve this by using models. A model in your application will represent the table to store this information. The model itself can then be used and be directly converted into a Django form. This makes sense as you want your forms to map to what you need to persist. This feature is excellent for ruling out any potential issues or errors.
The code for the model form is placed in the file forms.py
and implements the structure of the model, and you will learn more about both form types in more detail later in this lesson.
Working with Django form fields and data types
Often web applications collect data from the user through a HTML form and it’s sent to the server for processing. You create a HTML form using various form elements such as input elements Radio buttons, Drop-down lists, and Checkboxes.
Suppose the manager of Little Lemon has asked you to build a customer form containing a customer’s name and age. First, you build a HTML form that contains three input elements, one for the name, one for age, and one for the submit button.
Previously, you learned that Django creates and processes forms using the Form class. This class defines all the expected attributes that will construct and process the form.
Form Fields
Once you lay out the structure of the form, Form fields are the building blocks that help build the form. While fields are an integral part of models, they are especially important while using forms as they help define the visual element of the form.
The custom logic behind the fields is defined in the Fields class used inside the Form class in Django. When defining attributes, you can choose from various field types.
Field Types
CharField
: which accepts any string input and is equivalent to the text input element in HTML.EmailField
: which accepts input that follows email format. It’s equivalent to the email input element in HTML.IntegerField
: accepts only integers and is equivalent to the number type input element in HTML.MultipleChoiceField
: offers the choice of multiple options. It’s equivalent to the select and option elements in HTML.FileField
: allows you to choose a file for upload and is equivalent to the file type input element in HTML.
Field Arguments
Additionally, these form fields have different arguments that can be passed to them while specific arguments that can be passed vary according to the field and use. There are a few core arguments that are accepted in common among all the fields.
- Required : each field assumes the value is required by default. You can change this by setting required equal to false.
- Label : the argument helps specify a label for the field.
- Initial : initial values can be set for specific fields.
- Help-text : specify descriptive text for the field.
It’s important to remember that every form that you build will have different data requirements. For example, a customer feedback form or a survey-style form for a customer’s favorite menu items. Knowing what field type to use is essential to building effective forms.
You can edit the form further by passing a parameter such as a widget.
This Textarea
will override the default widget for it, which is the equivalent of rendering the input field present in HTML code.
The code works but suppose you want a smaller Textarea to display. You can pass a parameter inside the Textarea such as attributes with a certain number of rows,
NOTE
It’s also important to note that Django Form Fields have basic validation applied by default.
To help the user know what to add in each form field, you can use the label parameter. For example, add a label parameter with the text to enter an email address.
However, suppose you want to display all three choices simultaneously. You can achieve this by using another widget option with the value of RadioSelect
.
It’s important to know that these examples showcase just some of the available form fields and parameters you can use in Django. Exploring the Django documentation for all available options to help you create forms is a good idea.
Django fields
In this reading, you will learn about different field types in a model class.
Model
A model in Django is like any normal Python class. The ORM layer maps this model to a database table in the Django project. Each attribute of a model class represents a field in the table.
The Django ORM enables storing and retrieving data in tables, not by executing raw SQL queries, but by invoking the model methods.Â
A model class subclasses the django.models.Model
class. A typical definition of a model class is done inside the app’s models.py
file.
When you migrate this model (you need to include your app in the INSTALLED_APPS
setting), the myapp_person
table will be created as would be done by the CREATE TABLE
query:
Note that the first_name
and last_name
are the class attributes corresponding to the fields in the table.Â
Django automatically names the table as appname_modelname
, which you can override by assigning the desired name to db_table
parameter of the Meta class, to be declared inside the model class.
You should choose the model field type appropriate for the data stored in the mapped field.Â
The types are defined in django.forms
module. The choice of type determines the HTML widget to use when the form field is rendered. For example, for a CharField
, HTML’s text input type will be used.Â
Django also auto-creates the form based on model definitions (it is called ModelForm
), using field types.
Field properties
A Field object has common properties in addition to the field-specific properties.Â
primary_key
This parameter is False by default. You can set it to True if you want the mapped field in the table to be used as its primary key.
It’s not mandatory for the model to have a field with a primary key. In its absence, Django, on its own, creates an IntegerField
to hold a unique auto-incrementing number.
default
You can also specify any default in the form of a value or a function that will be called when a new object is created.
unique
If this parameter in the field definition is set to True, it will ensure that each object will have a unique value for this field.
choices
If you want to create a drop-down from which the user should select a value for this field, set this parameter to a list of two-item tuples.
Field types
The django.models
module has many field types to choose from.
CharField:Â
This is the most used field type. It can hold string data of length specified by max_lenth
parameter. For a longer string, use TextField
.
IntegerField:Â
The field can store an integer between -2147483648 to 2147483647. There are BigIntegerField
, SmallIntegerField
and AutoFieldtypes
as well to store integers of varying lengths.
FloatField:Â
It can store a floating-point number. Its variant DecimalField
stores a number with fixed digits in the fractional part.
DateTimeField
Stores the date and time as an object of Python’s datetime.datetime
class. The DateField
stores datetime.date
value.
EmailField
It’s actually a CharField
with an in-built EmailValidator
FileField
This field is used to save the file uploaded by the user to a designated path specified by the upload_to
parameter.
ImageFieldÂ
This is a variant of FileField
, having the ability to validate if the uploaded file is an image.
URLField
A CharField
having in-built validation for URL.
Relationship fields
There can be three types of relationships between database models:
- one-to-one
- one-to-manyÂ
- many-to-many
The django.models module has the following fields for establishing relationships between models.
ForeignKey
Â
It is used to establisha one-to-many relationship between two models. It requires two positional arguments - the model with which it is related, and the on_delete
option to define the behavior of the delete operation.
Suppose you have a Customer and Vehicle model with a one-to-many relationship. A customer can have more than one vehicle.
The on_delete
option specifies the behavior in case the associated object in the primary model is deleted. The values are:
CASCADE: deletes the object containing the ForeignKey
PROTECT: Prevent deletion of the referenced object
RESTRICT: Prevent deletion of the referenced object by raising RestrictedError
Now let’s expand upon these values in more detail:
CASCADE
If the on_delete
parameter is set to CASCADE
, deleting the reference object will also delete the referred object. Suppose a vehicle belongs to a customer. When the Customer is deleted, all the vehicles that reference the customer will be automatically deleted.
PROTECT
The effect of the PROTECT
option is the opposite of CASCADE
. It prevents the deletion of a referenced object if it has an object referencing it in the database. Suppose a vehicle belongs to a customer.
If a customer has vehicles, it cannot be deleted. It’s important to know that if you forcefully delete the customer, Django raises the ProtectedError
.
RESTRICT
The difference between PROTECT
and RESTRICT
is that when you delete the referenced object, the on_delete
option raises the RestrictedError
.
The deletion of the referenced object is allowed if it also references a different object that is being deleted in the same operation, but via a CASCADE
relationship.
Let’s use the example of an Artist model – a CASCADE
relationship with an Album and Song model. The Artist model, in turn, has a RESTRICT
relationship with the song model.
Next, you can create a few instances of these models:
You can safely delete the artist1
instance. If you try to delete artist2, the RestrictedError
is raised.
OneToOneField:Â
This field in one of the models establishes a one-to-one relationship between the two models.Â
Although a ForeignKey
field with unique=True
setting, behaves similarly, the reverse side of the relationship will always return a single object.
The following model definition demonstrates a one-to-one relationship between the college model and a principal model.
A college can have only one principal and one person can be a principal of only one college.
ManyToManyField:Â
This field helps in setting a many-to-many relationship between two models.Â
Here, multiple objects of one model can be associated with multiple objects of another model.Â
For example, in the case of Subject and Teacher models, a subject is taught by more than one teacher.Â
Similarly, a teacher can teach more than one subject. This is represented in the following model definitions:
In this reading you learned about the different fields to be used as the type of attributes in a model class.
Form API
In this reading item, you’ll explore the important features of the Form class defined in django.forms
module.
HTML Form
Almost every web application collects certain data from the user by presenting them with a form to fill out and submit. A form is a document wherein the user enters their responses at certain labeled placeholders. For example, a form that is used to register on a certain site, or the one used to fill your travel details for booking a ticket, or a job application form.
You can construct a form using HTML’s form tag and its various input elements (such as text, radio, and checkboxes, dropdowns and lists).
HTML has very little validation support for these elements. Hence, you need to use JavaScript functions to validate the data before submitting it to the server.
Django Form
Django framework includes a Form class, its attributes, and methods in the django.forms
module. This class is used as a base for a user-defined form design.
The attributes of the form are Field class objects. The forms module has a collection of Field types. These fields correspond to the HTML elements they eventually render on the user’s browser. For example, the forms.CharField
is translated to HTML’s text input type. Similarly, the ChoiceField
is equivalent to SELECT
in HTML. The Django form class representing the above Application form would be:
By convention, the user-defined form classes are stored in a forms.py file in the app’s package folder. So, if you have a Django app called myapp
, the above code is kept in myapp/forms.py
.
Django Form Fields
Out of the many available form field types, some of the most frequently used are as follows:
CharField: Translates to input type=text
HTML form element. If you want to accept a longer multiline text, set its widget property to forms.Textarea
IntegerField: Similar to a CharField but customized to accept only integer numbers. You can limit the value entered by setting min_value
and max_value
parameters.
FloatField: A text input field that validates if the input is a valid float number. Its variant DecimalField
accepts a float number of specified decimal places.
FileField: Presents an input type=file
element on the HTML form.
ImageField: Similar to FileFieldwith
added validation to check if the uploaded file is an image. The pillow library must be installed for this field type to be used.
EmailField: A CharField
that can validate if the text entered is a valid email ID.
ChoiceField: Emulates the HTML’s SELECT element. Populates the drop-down list with a choice parameter whose value should be a sequence of two item tuples.
The instance of the Form class translates to the HTML script of a form. When returned to the browser, the form is rendered.
Let us open the Django shell and check what the form object returns.
You’ll see the following HTML script:
Form Template
The form object thus translates to HTML script of form – minus the <form>
as well as the <table>
tag. To render it on a browser, you have to first write an HTML template and put the form object in jinja2
tag. Let us save the following form.html
file in the project’s templates folder.
Let there be a following view in the app’s views.py
file which renders the forms.html
template and sends the ApplicationForm
object as a context.
Inside the template, the form can be rendered in different ways. Instead of a tabular presentation of the form elements you can use the following variations:
{{ form.as_table }}
will render them as table cells wrapped in<tr>
tags. The form is rendered as a table by default.
Output:
{{ form.as_p }}
will render them wrapped in<p>
tags.
The form is displayed in the browser:
{{ form.as_ul }}
will render them wrapped in<li>
tags.
The form is renders in the browser:
{{ form.as_div }}
will render them wrapped in<div>
tags.
The form is renders in the browser:
Reading Form Contents
Note that the form’s action attribute is set to "/form"
path. So, you’ll provide a form()
view mapped to this URL. This function fetches the data submitted by the user. It may be used to add a new row in the database table, or for any other processing.
Inside the view, populate the form object with the POST data and check it is valid. The Form class provides is_valid()
method. It runs validation on each field and returns True if all field validations are passed.
Once the Form instance is validated, you can now access the data in individual field via the cleaned_data
attribute. It ensures that the field contains the output in consistent form. In our example, the three values in the three input elements are parsed to Python variables like this:
In this reading item on Forms API, you learned about Django Form and form fields. You also learned how the form is rendered and processed.
Creating Forms
First I need to create a file called forms.py inside the app directory. In this scenario I will create a form on the little lemon website that allows the employees to log their entry times of work.
The process of building forms in Django is very similar to creating models.
It’s important to remember to use the form method of post as I’m sending the data from the form and creating an object from it.
To finish this form code I have to add something called a CSRF token, which is simply a way of telling Django that the form data is safe.
Finally I pass the form that I’ve created.
You may notice that the form does not have any styling applied. Well I could use some CSS, I’m not going to just yet. Instead I want to demonstrate a trick to structure the form elements using paragraph tags.
Back in the file home.html I can modify how the form is rendered by amending the form to form.as_p
.
When I press the submit button, notice that Django also provides basic form validation where all the elements are required. If I want to change this I can pass a parameter inside the forms file. For each attribute I can type required = False
.
Similarly I can pass other parameters. For example inside the time log I can type help_text=
and then the text enter the exact time.
Finally I can open my HTML file to add some inline styling to the form. Inside the form declaration I add a background color.
Working with forms can be complex, so developers can use Django’s formed functionality to simplify and automate vast portions of this work. By creating forms this way, developers are guaranteed to add Django’s layer of security.
Model Form
what if you want to use them together to save entries entered in a form inside a database? Django provides a very efficient way to do that using ModelForm by providing a means to save received data as a response directly to the database.
The process of creating such a ModelForm is similar to that of creating a model and form. Just like in the case of model and form, Django provides another helper class called ModelForm that helps in an easier implementation.
Let’s take an example. Say you want to create a reservation form for the little lemon restaurant. In the example, you first import the model you want to bind with your form.Then you add implementation details for it using a meta class. And finally, you create an instance of that form.
NOTE
Note, that instead of having separate classes for form and model, you have just one that inherits the ModelForm and implements it.
Since this is an implementation that involves sending form data back as a response, you also need to add some implementation details about the post method inside the view.
Just as a reminder, notice the code in the forms.py file and how it is used to render a form in the browser.
Building on the project that’s already in place, let’s modify the form to use ModelForm this time. So, first to simplify, remove the shifts attributes.
And since this is a ModelForm, copy the contents and paste it inside the models.py file.
Next, you need to reconfigure all the details so that it matches the configuration code for a model.
Notice how the class name changed from log form to logger which is the name of the model.
Next, let’s go to forms.py again, delete the existing content and then create the ModelForm based on the model that is in place.
Instead of assigning individual fields, let’s just enter the value of all which will import all the fields inside that particular model.
Next, you must make sure that you register the model. For this, go to admin.py and update the details.
Next, switch to the views.py file. Once inside the view, notice that there is already some basic configuration that helps render the form.
If you recall, the form object, which this time is the ModelForm is passed inside a context dictionary which is then passed inside the render function.
Now, you must add some code that will help accept the form data and send it to the model database.
So, let’s add a conditional statement such as if request.method equal to post, next, add form equal to log form and then pass a request.post inside it.
What this code does is update the form object with the contents of post inside the request object.
Next, check out the form is valid. And if so, save the form using that save method.
You already have everything you need in terms of the form template. After you run the migrations, run the server.
Next, enter the name Kyle McGregor. And the time 11 minutes past 11. And once you press the Submit button, notice that the post method is logged on the console.
Additional resources
The following resources will be helpful as additional references in dealing with different concepts related to the topics you have covered in this module.
Models – official documentation
Migrations – official documentation
Detailed overview of Migrations
Previous one → 8.Models & Migrations | Next one → 10.Admin