Django is an effective web framework that provides robust tools for building web applications, including support for creating and processing web forms. Forms are an essential part of many web applications, as they allow users to input data and interact with the application meaningfully. Knowing how to make accessible and usable forms helps to keep the service simple.
ModelForm
This situation is familiar to many: a close friend who lives far away, someone from childhood, or a pen-friend you've never actually met. Holidays come, and you want to surprise them with a postcard. How can you do it? Well, it so happens that we're working hard on the hypergift service. With this service, you can send a postcard to any place worldwide.
If you only need to represent fields of one single model, which already contains all the information required for building a form: fields, help text, additional information, and so on, you can use a pre-tuned ModelForm class. It helps to create forms from an already existing model.
Let's create a model for Postcard in file models.py inside of the app, you are working on the following:
from django.db import models
TITLE_CHOICES = [
('MR', 'Mr.'),
('MRS', 'Mrs.'),
('MS', 'Ms.'),
]
class Postcard(models.Model):
address = models.CharField(max_length=255)
author = models.CharField(max_length=255)
compliment = models.CharField(max_length=1024)
usage = models.CharField(max_length=3, choices=TITLE_CHOICES)
date_of_delivery = models.DateField(blank=True, null=True)
email = models.EmailField()Using ModelForm, the only thing you need to do is to add Meta class inside the PostcardForm class, to connect it with Model Postcard and to list all the fields of the model we need to use in the form. It is possible to use all fields (fields = '__all__') or to apply the exclusion method (exclude) to define fields of the model we don't want to use.
from django.db import models
from django.forms import ModelForm
from .models import Postcard
class PostCardModelForm(ModelForm):
class Meta:
model = Postcard
fields = '__all__'
class PostCardModelFormOnly2(ModelForm):
class Meta:
model = Postcard
fields = ['address', 'date_of_delivery']It's possible to exclude fields from the model, for example like this:
class PostCardModelFormPartial(ModelForm):
class Meta:
model = Postcard
exclude = ['date_of_delivery']As you can see, ModelForm in simple cases, is simple and easy to understand!
You can redefine help_text notes, errors, and so on using the Meta class.
So now you can use PostCardModelForm the same way as PostcardForm. In views.py:
from .forms import PostCardModelForm
from django.views.generic.edit import FormView
class PostcardFormView(FormView):
form_class = PostCardModelForm
template_name = "postcard/form.html"
success_url = "/postcard/form"Finally, make a URL-mapper in urls.py:
from django.urls import path
from .views import PostcardFormView
urlpatterns = [
path('form/', PostcardFormView.as_view())
]Custom forms
Using a ModelForm class, as was shown above, is a good way if you only need to represent fields of one single model. But what if you need a more flexible way to create forms of any structure you need?
It can be connected with any model (or models) from the database. It is necessary if you deal with complicated or multiple relations between data objects.
To make a custom form, you inherit the class from django.forms.Form. The class provides means to render the form in templates, validate it and show exact errors in the input. Fields should be declared with specific types for correct validation of the user's input (don't worry, we'll discuss it further on).
Let's create a new form:
from django import forms
class PostcardForm(forms.Form):
address = forms.CharField(label='Destination Address')
author = forms.CharField(min_length=3)
compliment = forms.CharField(max_length=1024)
date_of_delivery = forms.DateField(input_formats=['%Y/%m/%d'])
email = forms.EmailField()Forms in templates
A form is an element of an HTML page, and Django provides tools to render its fields correctly. It also gives default methods to format fields as tables, unordered lists, or paragraphs.
Assume that we initialize a form with no arguments and save it in the postcard_form variable. We pass the context dictionary {'postcard_form': postcard_form} to a template and add csrf_token to prevent security issues:
<form method="post">
{% csrf_token %}
<table>{{ postcard_form.as_table }}</table>
<button type="submit">Submit</button>
</form>The method postcard_form.as_table converts the instance of the PostcardForm class to <tr>, <th> and <td> HTML tags with appropriate labels and attributes. The address field has a custom title in the class, so it also has the same label value on a page.
<th><label for="id_address">Destination Address:</label></th>In the browser, the form would look like this:
Other methods for rendering forms are form.as_p (converts forms to paragraphs) and form.as_ul (converts them to an unordered list).
Conclusion
Forms are an essential part of any web application, and Django provides developers with the tools they need to create effective and efficient forms. Furthermore, forms can be easily integrated into templates, allowing seamless user experiences. By leveraging Django's forms API and ModelForm features, developers can save time and effort in creating forms.