In our last tutorial, we have explained how to create and use forms with Django Framework In this article, we are going to explain another way of creating forms in Django Framework i.e. by using ModelForm class.
So let us create a Django project to explain you how to work with forms using ModelForm class provided by Django Framework. For those who have not read our last tutorials and for those who don't know how to create a Django project, here is a recap.
Creating a Django project
To create a directory for our project, we need to open the Command Prompt and type in the command -
django-admin startproject django_model_form
dhago-admin is a management utility for Django Framework, using which we could create a new project and much more.
startproject is a command to start a new Django project.
django_model_form is the name of our Django project and also the name of our project directory created in the current directory.
The startproject command gives us a sub-directory and files
Executing the startproject command has not only created a project directory named django_model_form, but has also created a file manage.py and another sub-directory
with the same name as the project directory, which also contains some Python files -
django_model_form is the root directory of our Django project, also known as the container of our project.
manage.py is a command-line utility which allows us to interact with Django project in various ways.
django_model_form sub-directory is actually a Python package for our project. We can import this package(a group of modules) and its contents just like we import any general Python package/module and its contents.
__init__.py is a file which allows our sub-directory django_model_form to be treated as a Python package.
settings.py is a file used for setting the configurations for our Django project.
urls.py is a file used to specify the URL declarations for our Django project, also known as a a table of contents.
wsgi.py is a file used as an entry-point for WSGI web-servers to serve your project.
Starting the development server
After creating the project directory and the files required to run our Django project, it is time to execute the Django Development Server. To do this,
we will have to open the command prompt, change the current directory to the root directory of our Django project and execute the following command.
python manage.py runserver
Executing the above mentioned command will trigger the Django Development Server in action, as you can see in the picture below.
E:\Django Projects\django_model_form>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 16 unapplied migration(s). Your project may not work properly until you
apply the migrations for app(s): admin, auth, contenttypes.
Run 'python manage.py migrate' to apply them.
September 19, 2019 - 17:37:35
Django version 2.2.1, using settings 'django_model_form.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Now that you have successfully started the Django development server, it is time to visit the http://127.0.0.1:8000/ link and you will see a webpage displaying a congratulatory message, as shown below.
Note: The runserver command runs the Django development server at the port 8000.
Creating an app in our project
A project may contain one or multiple applications. As we have already created a project, now let us create a welcome application in it which welcomes the user. This application will be created right under our root - project directory django_model_form.
To create an application, we have to open another window command prompt, change the current directory to the root directory of our Django project and execute the following command -
python manage.py startapp model_form
The command startapp in combination with manage.py utility is used to create an app of a project, using which we have created an app named - model_form.
Executing the startapp command has not only created an application directory named model_form in the root - project directory, but has also created the following set of Python files -
Next, we are going to create an HTML template file within our application folder model_form, we will name this file template.htm.
In this HTML template file, we will define an HTML form with its basic elements:
An action attribute, used to specify the form handler.
An HTTP method, used to submit the form data. This method could be POST or GET.
template.htm
<html>
<head><title>Django Framework with model_form - Decodejava.com</title></head>
<body>
Welcome! Please fill the form below:
<form action="form_submit/" method="post">
{% csrf_token %}
{{ form|linebreaks }}
<input type="submit" value="OK">
</form>
</body>
</html>
This HTML template file contains two parts:
In this HTML template file, we have specified a variable - form within the double curly brackets {{ }}.
This form variable allow us to access the form fields specified in the model_form.py(going to create it next) and dynamically insert them in this HTML template file.
The static part, such as a submit button which actually sends the form data.
Note:
We have used the form variable with the linebreaks filter, which installs an HTML linebreak <br/> in the HTML template file, after displaying each form field specified the model_form.py.
Creating a model class
Next, we have to create a model class, where each model class corresponds to a database table on which we could perform database operations by using the Django Framework.
This model class will contain fields name and other metadata, which can be used to create a table in database and also dynamic HTML form.
Each model class is a subclass of django.db.model.Model class.
Note: The upcoming model class - CustomerInfo is defined in the file models.py, which is already created and stored in our application directory, customer. Let us just copy and paste the following code in models.py.
models.py
from django.db import models
class CustomerInfo(models.Model):
first_name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField(max_length=100)
married = models.BooleanField()
def __str__(self):
return (self.first_name + ', ' + self.age + ', ' + self.email + ', ' + self.married)
Each model class could have a number of class variables, where each class variable represents a database field in the database table.
Each database field is represented by an appropriate Field class, such as -
CharField class is used to specify the character field
IntegerField class is used to specify an integer field.
EmailField class is used to specify a email field.
BooleanField class is used to specify a boolean field.
The name of the field is used a column name in the database table.
Note: Django automatically gives an integer primary key field called id to each model class.
Creating the Form class - forms.py
Up next, we are going to create a form class named NameForm by extending the in-built ModelForm class. The ModelForm class is used when we want to create a form by using fields specified in model class i.e. database fields.
To create a ModelForm class, we need to add a class Meta inside it. Inside the Meta class, we instantiate the Django Model class by specifying the name of model class(models.py) for which HTML form will be created and the fields of the model class in an array.
This file will be created within the application i.e. model_form folder.
forms.py
from django.forms import ModelForm
from model_form.models import CustomerInfo
class NameForm(ModelForm):
class Meta:
model = CustomerInfo
fields = ['first_name', 'age', 'email', 'married']
Creating the view - view.py
Once we have created the HTML template file in the application, we will also need to create a view which comprises of one of more view functions.
A view function is simply a Python function which takes an HttpRequest from the HTML template file and returns an HttpResponse with the values of the variables specified and requested by the HTML template file, such as - form variable specified within the HTML template file.
Note: This view functions are defined in the file view.py, which is already created and stored in our application directory, model_form. Let us just copy and paste the following code in view.py.
view.py
from django.shortcuts import render
from .forms import NameForm
# This view function is used when the form is requested for the first time to display it to the user
def get_form(request):
form = NameForm()
return render(request, 'template_ex.htm', {'form': form})
# This view function is called when submit button is pressed by the user after filling the form details.
def process_form(request):
# Handling the POST request to process the form data
if request.method == 'POST':
# Creating a form instance and populating it with data from the request
form = NameForm(request.POST)
# Check whether the form data is valid, if yes, a thanks page is sent back.
if form.is_valid():
return render(request, 'thanks.htm', {'form': form})
In this view.py file, we have imported the render function from the django.shortcuts module and have defined two view functions:
get_form, used to display the form to the user for the first time.
process_form, used to process the form data sent by the user.
The view function - get_form takes an HttpRequest object in its parameter and we have named this parameter - request.
Note:Each view function takes an HttpRequest object in its first parameter and it could named anything but its typically named - request.
In this view function, we have simply created an object of NameForm Form class.
To initiate the process of rendering, we call the render() method, which replaces the form variable declared in HTML template file with the values of form fields specified in the NameForm class.
The render() method requires three parameters passed to it:
Request - An incoming request.
Path to the HTML template - This is a path relative to the path specified in settings.py file.
Context - Since, Django 1.8+ version, the render() method takes a Context, which should be represented by a dictionary of variables needed in the template.
On call, the render() method renders the request from template_ex.htm page and returns an HttpResponse object with the rendered form fields.
The process_form view function processes the form data submitted by the user, when the form is sent by using the HTTP POST method.
In the process_form view function, we have called the is_valid() method on the Form instance(referring to NameForm), which runs the validation checks on all the form fields specified in the NameForm class.
If the form data send by the user is valid then we have called the render() method to render the thanks.htm webpage.
Installing the Model
Next, we need to add the app model_form to our project by adding the reference to its configuration class in the INSTALLED_APPS property within the settings.py file(which is present within the django_model_form folder).
The ModelFormConfig configuration class named ModelFormConfig is present in the apps.py file within the app model_form folder.
Within the settings.py file, you need to locate the property INSTALLED_APPS and copy-paste the full-path of this configuration file against it, as shown below and save the file.
Now Django Framework will include the model_form app on executing this Django project.
Creating the thanks.htm webpage
Once a user has correctly filled the form and have submitted it, a thanks.htm webpage is displayed to the user.
thanks.htm
<html>
<head><title>Django Template System - Decodejava.com</title></head>
<body>
Thank you for submitting the form.
</body>
</html>
Mapping URL to view
After creating the view functions of an application, we need to specify the mapping between a URL and each view function in a file named - urls.py. The file urls.py is simply coded in Python and we will have to create the urls.py file in the folder of our application, model_form.
The use of mapping a URL to the view function is, when this URL is requested by the user, its mapped view function is executed and a response is returned.
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.get_form),
path('form_submit/', views.process_form),
]
As you can see in the file urls.py, we have imported the path() function from the module django.urls.
The path() function has been passed the two must arguments -
An empty string to specify the URL pattern, specified by ' ', this empty string will be matched to the view function - get_form.
A string 'form_submit/' will be matched to the view function - process_form, defined in the application's views.py.
Note:
This URL pattern specified in the application's urls.py file gets added to another URL pattern, specified in the project's urls.py file(we are going to create it next), and the combined path will be matched to the view functions defined in the application's views.py.
Pointing the project URL to application URL
Next, we are going to point the project URL(urls.py) to the application URL(urls.py) by using the include() function. For this, we will open the file urls.py in the root - project directory, django_model_form, and copy-paste the following code.
urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('welcome/template/', include('model_form.urls')),
]
As you can see in the file urls.py, we have imported the path() and include() function from the module django.urls.
The path() function has been passed the two must arguments -
A string to specify the URL pattern - 'welcome/template/'. This is the relative path to the template.
This URL pattern, combined with the URL pattern defined in the application's urls.py will be matched to the view function - templ, which is specified in the application urls.py file(stored in the application directory model_form). Therefore we have used the include() function to include and refer to the application's urls.py file.
How to load the HTML template file.
Next, we are going to show how to load the above created HTML template file template.htm, which is stored within our application folder model_form.
To load the HTML template file, we need to specify its full path in the configuration file - settings.py, which is stored in the project folder. For our example, you can find this file in the sub-directory django_model_form within our project django_model_form i.e. - django_model_form/django_model_form/settings.py.
Within the settings.py file, you need to locate the property DIRS and copy-paste the full-path to the HTML template file against it, as shown below and save the file.
And finally, it's time to execute our Django project with templates.
Executing the application of our project
To execute the model_form application of our project django_model_form, we just have to enter the address - http://127.0.0.1:8000/welcome/template/. This displays the form as shown below.
As you can see in the picture, the string welcome/template in the URL is the URL-pattern which gets matched to the URL pattern specified in the project urls.py file, which calls the application's urls.py and its associated view function - get_form(in the application) is executed and its response i.e. form with its elements(fields) is displayed within the HTML template file template.htm.
Next, when a user has filled the form with data in correct format.
On clicking the submit button, the user is displayed a thank you webpage(thanks.htm), as shown below.
Phew! This concludes the tutorial of creating and using an HTML form using Django Framework. See you in the next one!