Sharing is caring 🙂

In this tutorial, we will cover what Django forms are and why they are useful in web development. Django forms are a way to create and handle HTML forms in a Django web application. They provide a convenient way to interact with user input and validate data, as well as perform actions based on the submitted form data.

Django forms are created using the Form class and are composed of Field objects, which represent the different input elements of the form. The Form class allows you to specify the fields to include in the form, as well as any validation rules or custom behavior you want to apply to the form.

Using Django forms can greatly simplify the process of handling user input in a Django application and make it easier to ensure that the submitted data is valid and meets the application’s requirements.

Setting Up a Django Form in a View

To set up a Django form in a view, you will need to first import the Form class from Django’s forms module. Then, you can create a form class by subclassing Form and defining the fields you want to include.

Here is an example of a simple form class that includes a single text field:

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(label='Your Name')

Once you have defined your form class, you can use it in a view by instantiating an instance of the form and passing it to the template context. Here is an example of how you might do this in a view function:

from django.shortcuts import render
from .forms import ContactForm

def contact(request):
    form = ContactForm()
    return render(request, 'contact.html', {'form': form})

This will make the form available to the template as the form variable, which you can then use to render the form in the template.

Rendering a Django Form in a Template

To render a Django form in a template, you can use the {% for %} template tag to loop through the form’s fields and render them one by one. The {% for %} tag allows you to access the current field’s label, name, and any errors that might have occurred during form validation.

Here is an example of how you might use the {% for %} tag to render a form in a template:

<form method="post">
  {% csrf_token %}
  {% for field in form %}
    <div class="form-group">
      {{ field.label_tag }} {{ field }}
      {% if field.errors %}
        <div class="invalid-feedback">
          {% for error in field.errors %}
            {{ error }}
          {% endfor %}
        </div>
      {% endif %}
    </div>
  {% endfor %}
  <button type="submit" class="btn btn-primary">Submit</button>
</form>

This template code will render the form fields and labels, as well as display any errors that might have occurred during form validation.

Note: Don’t forget to include the {% csrf_token %} template tag to protect against cross-site request forgery attacks.

You can also customize the way each field is rendered by using the field.as_widget template tag and passing in any additional HTML attributes that you want to include. For example:

{{ field.as_widget(attrs={'class': 'form-control'}) }}

This will add the form-control class to the field’s HTML element, which can be used to apply styling using CSS.

Customizing Form Field Labels and Placeholders

To customize the label and placeholder of a form field in Django, you can use the label and widget arguments when defining the field in the form class.

The label argument allows you to specify the text that will be displayed as the field’s label. For example:

name = forms.CharField(label='Your Name')

The widget argument allows you to specify the HTML widget that will be used to render the field. You can use this argument to set the placeholder attribute of the field’s HTML element. For example:

email = forms.EmailField(widget=forms.TextInput(attrs={'placeholder': 'Enter your email address'}))

You can also override the default label and placeholder values for a form field in the template by using the {% with %} template tag. For example:

{% with form.email as field %}
  {{ field.label_tag }} {{ field }}
  {% if field.errors %}
    <div class="invalid-feedback">
      {% for error in field.errors %}
        {{ error }}
      {% endfor %}
    </div>
  {% endif %}
{% endwith %}

This template code will render the email field with the default label and placeholder, but you can easily override these values by setting the label and placeholder variables in the {% with %} block.

{% with form.email as field %}
  {% with label='Email Address' placeholder='Enter your email address' %}
    {{ field.label_tag }} {{ field }}
    {% if field.errors %}
      <div class="invalid-feedback">
        {% for error in field.errors %}
          {{ error }}
        {% endfor %}
      </div>
    {% endif %}
  {% endwith %}
{% endwith %}

This will render the email field with the customized label and placeholder.

Validating Form Data with Form Classes

To validate form data using form classes in Django, you can use the clean method of the form class. The clean method is called when the form is submitted and allows you to perform any custom validation that you need.

Here is an example of a form class that includes a clean method to validate the form data:

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(label='Your Name')
    email = forms.EmailField(label='Your Email')
    message = forms.CharField(widget=forms.Textarea)

    def clean(self):
        cleaned_data = super().clean()
        name = cleaned_data.get('name')
        email = cleaned_data.get('email')
        message = cleaned_data.get('message')

        if not name and not email and not message:
            raise forms.ValidationError('You have to write something!')

In this example, the clean method checks if all of the form fields are empty, and if they are, it raises a validation error.

You can also use the clean_<field_name> method to perform validation on a specific form field. For example:

def clean_email(self):
    email = self.cleaned_data.get('email')
    if not email.endswith('@example.com'):
        raise forms.ValidationError('Email must be from example.com')
    return email

This clean_email method checks if the email field ends with @example.com and raises a validation error if it does not.

To display form errors in the template, you can use the {% if %} template tag to check if the form has any errors, and then use the {{ form.non_field_errors }} template variable to display the errors. Here is an example of how you might do this:

{% if form.errors %}
  <div class="alert alert-danger">
    {{ form.non_field_errors }}
  </div>
{% endif %}

This template code will display any form errors that are not associated with a specific form field. To display errors for a specific field, you can use the {{ field.errors }} template variable.

{% if field.errors %}
  <div class="invalid-feedback">
    {% for error in field.errors %}
      {{ error }}
    {% endfor %}
  </div>
{% endif %}

This template code will display any errors for the current field being rendered.

Processing Form Data in the View

To process form data in the view, you can use the request.POST attribute to access the submitted form data. The request.POST attribute is a dictionary-like object that contains the submitted form data.

Here is an example of how you might process form data in a view function:

from django.shortcuts import render
from .forms import ContactForm

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            name = form.cleaned_data['name']
            email = form.cleaned_data['email']
            message = form.cleaned_data['message']
            # Process the form data here
            return render(request, 'success.html')
    else:
        form = ContactForm()
    return render(request, 'contact.html', {'form': form})

In this example, the view function first checks if the request method is POST, which indicates that the form has been submitted. If the request method is POST, the view function creates a new ContactForm instance and passes the request.POST data to it.

The form is then validated using the is_valid method, which checks if the form data is valid according to the form’s validation rules. If the form is valid, the view function can access the cleaned form data using the form.cleaned_data dictionary.

If the form is invalid, the form will be rendered again with the errors displayed to the user.

Note: Don’t forget to include the {% csrf_token %} template tag in the form to protect against cross-site request forgery attacks.

Displaying Form Errors

To display form errors in Django, you can use the {% if %} template tag to check if the form has any errors, and then use the {{ form.non_field_errors }} template variable to display the errors. Here is an example of how you might do this:

{% if form.errors %}
  <div class="alert alert-danger">
    {{ form.non_field_errors }}
  </div>
{% endif %}

This template code will display any form errors that are not associated with a specific form field. To display errors for a specific field, you can use the {{ field.errors }} template variable.

{% if field.errors %}
  <div class="invalid-feedback">
    {% for error in field.errors %}
      {{ error }}
    {% endfor %}
  </div>
{% endif %}

This template code will display any errors for the current field being rendered.

You can also customize the way errors are displayed by using the error_css_class and required_css_class attributes of the form class. The error_css_class attribute allows you to specify the CSS class that will be added to form fields that have errors, while the required_css_class attribute allows you to specify the CSS class that will be added to form fields that are required.

For example:

class ContactForm(forms.Form):
    name = forms.CharField(label='Your Name', error_css_class='is-invalid', required_css_class='is-required')
    email = forms.EmailField(label='Your Email', error_css_class='is-invalid', required_css_class='is-required')
    message = forms.CharField(widget=forms.Textarea, error_css_class='is-invalid', required_css_class='is-required')
    error_css_class = 'is-invalid'
    required_css_class = 'is-required'

In this example, the error_css_class and required_css_class attributes are set for each field, as well as for the form as a whole. This will add the is-invalid class to fields that have errors and the is-required class to required fields.

You can then use these CSS classes to style the form fields and errors in your CSS file. For example:

.is-invalid {
  border-color: #dc3545;
}

.is-invalid ~ .invalid-feedback {
  display: block;
}

.is-required {
  color: #6c757d;
}

This CSS code will set the border color of fields with errors to red and display the error messages, as well as set the color of required fields to a light gray.

Working with File Uploads in Forms

To work with file uploads in Django forms, you can use the FileField form field. The FileField form field allows users to select and upload a file as part of the form submission.

Here is an example of a form class that includes a FileField:

from django import forms

class FileForm(forms.Form):
    file = forms.FileField()

To render the FileField in a template, you can use the {{ field }} template tag. For example:

<form method="post" enctype="multipart/form-data">
  {% csrf_token %}
  {{ form.file }}
  <button type="submit" class="btn btn-primary">Submit</button>
</form>

Note: Don’t forget to include the enctype="multipart/form-data" attribute on the <form> element to allow file uploads.

In the view, you can access the uploaded file using the request.FILES attribute. The request.FILES attribute is a dictionary-like object that contains the uploaded files.

Here is an example of how you might process an uploaded file in a view function:

from django.shortcuts import render
from .forms import FileForm

def file_upload(request):
    if request.method == 'POST':
        form = FileForm(request.POST, request.FILES)
        if form.is_valid():
            file = request.FILES['file']
            # Process the uploaded file here
            return render(request, 'success.html')
    else:
        form = FileForm()
    return render(request, 'file_upload.html', {'form': form})

In this example, the view function first checks if the request method is POST, which indicates that the form has been submitted. If the request method is POST, the view function creates a new FileForm instance and passes the request.POST and request.FILES data to it.

The form is then validated using the is_valid method, which checks if the form data is valid according to the form’s validation rules. If the form is valid, the view function can access the uploaded file using the request.FILES['file'] attribute.

If the form is invalid, the form will be rendered again with the errors displayed to the user.

Common Form Fields

Django provides several built-in form field classes that you can use to create forms. Here is a list of the built-in field classes and a summary of what they are used for:

  • BooleanField: A form field that allows the user to select a boolean value (True or False).
  • CharField: A form field that allows the user to enter a single line of text.
  • ChoiceField: A form field that allows the user to select a value from a list of choices.
  • DateField: A form field that allows the user to enter a date.
  • DateTimeField: A form field that allows the user to enter a date and time.
  • DecimalField: A form field that allows the user to enter a decimal value.
  • EmailField: A form field that allows the user to enter an email address.
  • FileField: A form field that allows the user to select and upload a file.
  • FloatField: A form field that allows the user to enter a floating point number.
  • ImageField: A form field that allows the user to select and upload an image file.
  • IntegerField: A form field that allows the user to enter an integer.
  • MultipleChoiceField: A form field that allows the user to select multiple values from a list of choices.
  • RegexField: A form field that allows the user to enter a value that matches a regular expression.
  • SlugField: A form field that allows the user to enter a value that is suitable for use as a slug.
  • TimeField: A form field that allows the user to enter a time.
  • URLField: A form field that allows the user to enter a URL.
Sharing is caring 🙂