Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Django uses a form template


May 14, 2021 Django


Table of contents


Brief introduction

Unless you plan to set up a content-only website and application and do not accept visitor input, you will need to understand and use the form.

Django provides a range of tools and libraries to help you build forms to accept input from site visitors, and then process and respond to input.


HTML form

In HTML, a form is a collection of internal elements. Allows visitors to perform actions such as entering text, selecting options, operating objects, or controls, and then sending the information back to the server.

Some of these form interface elements (text input or check boxes) are built into the HTML itself. O thers are much more complicated. An interface that pops up a date selector or allows you to move sliders or manipulate controls typically uses JavaScript and CSS, as well as HTML forms, to achieve these effects.

The form and its elements must also specify two things:

  • Where: The URL to which the data corresponding to the user input should be returned
  • How: The HTTP method through which the data should pass

Django form processing

Django's form processing: The view gets the request, does whatever it takes, including reading the data from the model, and then generates and returns the HTML page (from the template), and we pass a context containing the data to be displayed. Complicating matters, the server also needs to be able to process user-provided data and re-display the page in the event of any errors.

Key elements of Django form processing:

  1. The default form is displayed the first time the user requests it. T he form may contain blank fields (for example, if you are creating a new record), or it may be pre-populated with initial values (for example, if you want to change records, or if you have a useful default initial value). At this point, the form is called unbound because it is independent of any data entered by the user (although it may have an initial value).
  2. Receive data from the submission request and bind it to the form. Binding data to the form means that the data entered by the user and any errors are desirable when we need to re-display the form.
  3. Clean up and validate the data. C leaning up data cleanses the input (for example, removing invalid characters that might be used to send malicious content to the server) and converting it to a consistent Python type. Verify that the check value is appropriate for the field (e.g., not too short or too long in the correct date range, etc.)
  4. If any data is invalid, re-display the form, this time using any user-populated values, and the error message for the problem field.
  5. If all data is valid, do the necessary actions (e.g. save data, send forms and emails, return search results, upload files, etc.)
  6. When you're done, redirect the user to another page.

The Django form is used in two ways:

  • GET
  • POST

GET method

  1. The browser requests a page
  2. When search engines retrieve keywords

The GET method is to display the data obtained from the user's side by key-value pairs, and then combine it into a whole string by "and" and finally add "? " , the combined string is stitched into the URL to generate a url address. I t is neither suitable for large amounts of data nor for binary data, such as images. W eb GET use GET to manage form requests are at risk: it is easy for an attacker to mimic a form request to access sensitive parts of the system. G ET applies only to requests that do not affect the state of the system. Such as the Web search form class, it can easily request to the URL to share, submit and other operations.

POST method

  1. The browser packages the data
  2. Transfers in encoded form
POST can change any request for system state, and the POST method allows the browser to package the form data, then transmit it encodedly, and then send it to the server and receive a response to it.

Django's role in the form

Working with tables is a complex business. Consider Django's administrators, who may need to prepare several different types of large amounts of data, display it as a table, render it as HTML, edit it using a convenient interface, return it to the server, validate and clean it up, and then save or pass it on for further processing.

Django's form functionality simplifies and automates most of the work and is more secure than most programmers can do in writing their own code.

Django handles three different parts of the work involving forms:

  • Prepare and reorganize the data to make it ready for rendering
  • Create HTML forms for your data
  • Receive and process forms and data submitted by customers

It's possible to write code to do it all manually, but Django's can take care of it all for you.

Form in Django

We've briefly described HTML forms, but HTML is only part of the mechanism required.

In the context of a Web application, "form" may refer to the HTML, form, or the Django that Form generates it, or the structured data returned at the time of submission, or the end-to-end working collection of those parts.

Django Form class

At the heart of the component system is Django's Form class. Classes and Django models describe the logical structure of an object, behave in much the same way as they represent its part to us, and a Form class describes a form and determines how it works and how it looks.

Just as the fields of the model class map to the database fields, the fields of the form class map to html forms and inputs. ( A maps the fields of the model class to html forms through; ModelForm, which the Django administrator is based on.)

The field of the form itself is a class. T hey manage form data and perform validation when the form is submitted. A DateField and FileField handle is very different types of data, and there are different things to do.

Form fields are represented to the user in the browser as HTML widgets - a user interface mechanism. Each field type has an appropriate default widget class, but you can override them as needed.

Instantize, process, and render forms

When rendering objects in Django, it is common to:

  1. Get it in the view (for example, get it from a database)
  2. Passed to the template context
  3. Use template variables to extend it to HTML tags

Rendering a form in a template involves almost the same work as rendering any other type of object, but there are some key differences.

For model instances that do not contain data, it is almost useless to do anything in the template. On the other hand, rendering an unfilled form makes sense - that's what we do when we want users to populate it.

Therefore, when we work with a model instance in a view, we typically retrieve it from the database. When we work with a form, we usually instantiate it in the view.

When instantiated forms, we can choose to leave them blank or pre-populated, for example:

  • Data from saved model instances (e.g. management forms for editing)
  • Data we collect from other sources
  • Data received from previous HTML form submissions

The last of these situations is the most interesting because it allows users to read not only the site, but also send messages to it.

The form of the build

Much remains to be done in this regard

Suppose you want to create a simple form on your site to get a user name. You need this in the template:

<form action="/your-name/" method="post">
    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
    <input type="submit" value="OK">
</form>

This tells the browser/your-name/use the POST method to return form data to the URL. I t displays a text field marked "Your Name:", and a button marked OK." If the template context contains a current_name variable, it will be used to prefill your_name field.

You will need a view to render the template that contains the HTML form, and you will be able to provide current_name the appropriate fields.

After the form is submitted, the POST request sent to the server will contain the form data.

You will now also need a view corresponding to the /your-name/URL, which will find the appropriate key/value pair in the request and then process it.

This is a very simple form. In fact, a form may contain dozens or hundreds of fields, many of which may need to be pre-populated, and we might want the user to complete a few edit-submit loops before ending the operation.

Even before submitting a form, we might need to do some validation in the browser;

At this point, it's much easier for Django to do most of the work for us.

Create a form in Django

This Form class

We already know what we want HTML forms to look like. Our starting point in Django is:

the forms.py
from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label='Your name', max_length=100)

This defines a class that Form has a single field your_name a single field. We applied a human-friendly label to this field, which will appear on the label when rendered (although in this case, the label we specify is actually the same label that is automatically generated when the label is omitted).

The maximum allowed length of a field is determined by max_length. T here are two things. I t is placed on maxlength"100" HTML (so the browser should first prevent the user from entering more than that number of characters). This also means that when Django receives the form back from the browser, it verifies the length of the data.

A Form instance has a is_valid () method that runs on all field validaters. When this method is called, if all fields contain valid data, it will:

  • Return true
  • Place the form's data cleaned_data its properties.

The first time you render, the entire form looks like this:

<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100" required>

Please note that it does not contain a label or submission button. We must provide this information in the template.

View

The form data sent back to the Django site is processed by the view, usually the same as the view of the publishing form. This allows us to reuse some of the same logic.

To work with a form, we need to instantiate its instantiated URL in the view as:

the views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render

from .forms import NameForm

def get_name(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, 'name.html', {'form': form})

If we reach this view through a GET request, it creates an empty form instance and places it in the context of the template to be rendered. This is what we can expect when we first visit the URL.

If the form is submitted using a POST request, the view creates the form instance again and populates the form instance with the data in the request: this is called binding data to the form (now the binding form). f orm = NameForm(request. POST)

We call the form is_valid () method, and if it's not True, we return a template with the form. This time, the form is no longer empty (unbound), so the HTML form is populated with previously submitted data, where it can be edited and corrected as needed.

If is_valid () True, we will now be able to cleaned_data validated form data in its property. We can use this data to update the database or do other processing, and then send http redirects to the browser to tell it what to do next.

Template

We don't need to .html many things in the name template:

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>

All fields and their properties of the form will be unzipped into HTML tags through Django's template language. {{ form }}

Forms and cross-site requests for counterfeit protection

Django comes with easy-to-use cross-site requests for counterfeit protection. W hen submitting a form with POST CSRF protection enabled, csrf_token the timeplate tag as in the previous example. However, because CSRF protection is not directly associated with the form in the template, this label is omitted in the following examples in this document.

HTML5 input type and browser validation

If the form includes URLField, an EmailField, or any whole number segment type, Django uses url, email, and number HTML5 input types. B y default, browsers can apply their own validation on these fields, which may be more rigorous than Django's. If you want to disable this behavior, set properties on the form label or specify other widgets on the field, such as TextInput.

Now we have a working Web form that is described by Django as Form, processed by the view and rendered as HTML.

That's all you need to get started, but the form framework gives you more convenience. Once you understand the basics of the above process, you should be prepared to understand the other functions of the form system and to learn more about the underlying machinery.

More about the Django Form class

All form classes are created as django.forms.Forms.Forms or sub-classes. Y ou can think of modelForm as a sub-class Form. Form and ModelForm actually inherit common functionality from the (private) BaseForm class, but this implementation detail is rarely important.

Models and forms

In fact, if your form will be used to add or edit the Django model directly, ModelForm can save a lot of time, effort, and code because it can build forms as well as the appropriate fields and their properties from a Model class.

Bind form instances and unbound form instances

The difference between bound and unbound forms is important:

  • Unbound forms do not have the data associated with them. When rendered to the user, it will be empty or contain the default value.
  • The binding form has submitted data, so it can be used to determine whether the data is valid. If an invalid binding form is rendered, it may contain an inline error message telling the user what data to correct.

The form'is_bound properties tell you if the form is bound to data.

More fields

Consider a form that is more useful than the smallest example above, which we can use to implement the "Contact Me" feature on a personal website:

the forms.py
from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

We used the previous form of a single your_name, a CharField. I n this case, our form has four fields: subject, message, sender, and cc_myself. C harField, EmailField and Boolean Field have only three field types available; The full list can be found in the Form field.

The widget

Each form field has a corresponding Widget class, which in turn corresponds to an HTML form widget, for example. <input type="text">

In most cases, the field will have a sensible default widget. F or example, by default, a CharField will have a widget that generates a in HTML TextInput. I f you want, you can specify the appropriate widget when you define the form field, just as we did with the field. <input type="text"><textarea>message

Field data

Regardless of the data submitted through the form, once the is_valid() (and is_valid)) is returned to True by calling, the validated form data will be in form.cleaned_data dictionary. This data will convert you well to the Python type.

Attention

At this point, you can still access unverified data directly. POST, but the validated data is better.

In the contact form example above, the cc_myself will be Boolean. Similarly, fields such as Integer Field and Float Field convert values to Python int and fields, respectively.

Here's how to handle form data in the view that handles this form:

the views.py
from django.core.mail import send_mail

if form.is_valid():
    subject = form.cleaned_data['subject']
    message = form.cleaned_data['message']
    sender = form.cleaned_data['sender']
    cc_myself = form.cleaned_data['cc_myself']

    recipients = ['[email protected]']
    if cc_myself:
        recipients.append(sender)

    send_mail(subject, message, sender, recipients)
    return HttpResponseRedirect('/thanks/')

Tip

For more information about sending e-mail from Django, see Sending e-mail.

Some field types require some additional processing. F or example, files uploaded using a form require different processing (which can lead to a request. F ILES is not from which to retrieve their request. P OST)。 For more information about how to handle form upload files, see Binding uploaded files to a form.

Work with the form template

All you need to do to put a form into a template is put an instance of the form into the context of the template. T herefore, if your form is called in context by form, it and elements are rendered appropriately. {{ form }}<label><input>

Form a rendering option

Attach table template furniture

Don't forget that a form of output doesn't include controls around the hashtag, or the form's submit. You must provide these yourself.

There are other output options for the pair:

  • They are form.as_table as table cells wrapped in the label
  • Wrap form.as_p them in the hashtag
  • Wrap form.as_ul them in the hashtags

Please note that you must provide your own surroundings with the elements of the environment.

This is the output of our instance: form.as_p

<p><label for="id_subject">Subject:</label>
    <input id="id_subject" type="text" name="subject" maxlength="100" required></p>
<p><label for="id_message">Message:</label>
    <textarea name="message" id="id_message" required></textarea></p>
<p><label for="id_sender">Sender:</label>
    <input type="email" name="sender" id="id_sender" required></p>
<p><label for="id_cc_myself">Cc myself:</label>
    <input type="checkbox" name="cc_myself" id="id_cc_myself"></p>

Note that the ID properties of each form field are set to id_, and are referenced by the accompanying label tag. T his is important to ensure that forms are accessible to assistive technologies, such as screen reader software. You can also customize how labels and IDs are generated.

For more information, see Output forms as HTML.

The manual rendering field

We don't have to have Django unzip the form fields; we can do it manually as needed (for example, allow us to reorder the fields). E ach field can be used as a property for the form and will be rendered appropriately in the Django template. For example: form.name_of_field.

{{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.subject.errors }}
    <label for="{{ form.subject.id_for_label }}">Email subject:</label>
    {{ form.subject }}
</div>
<div class="fieldWrapper">
    {{ form.message.errors }}
    <label for="{{ form.message.id_for_label }}">Your message:</label>
    {{ form.message }}
</div>
<div class="fieldWrapper">
    {{ form.sender.errors }}
    <label for="{{ form.sender.id_for_label }}">Your email address:</label>
    {{ form.sender }}
</div>
<div class="fieldWrapper">
    {{ form.cc_myself.errors }}
    <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
    {{ form.cc_myself }}
</div>

You can also use to generate a complete element label_tag(). For example:

<div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject }}
</div>

The error message in the form of a rendering

Of course, the price of this flexibility is more work. S o far, we don't have to worry about how to display form errors, as this has been resolved for us. I n this example, we must ensure that all errors for each field and all errors for the entire form are handled. N ote at the top of the form and template lookup to find errors on each field. {{ form.non_field_errors }}

Use to display a list of formatting errors and display as a sequenceless table. It might look like: form.name_of_field.errors.

<ul class="errorlist">
    <li>Sender is required.</li>
</ul>

The CSS class errorlist of the list allows you to style the appearance. If you want to further customize the display of errors, you can do so by traversing them:

{% if form.subject.errors %}
    <ol>
    {% for error in form.subject.errors %}
        <li><strong>{{ error|escape }}</strong></li>
    {% endfor %}
    </ol>
{% endif %}

Non-field errors (and/or hidden field errors that appear at the top of the form when using, for example, accessibility tools form.as_p ()) are rendered through additional categories, nonfield to help separate them from field-specific errors. For example, it form.non_field_errors looks like this:

<ul class="errorlist nonfield">
    <li>Generic validation error</li>
</ul>

For more information about errors, styles, and how to use form properties in templates, see the Forms API.

Traverse the fields of the form

If you use the same HTML for each form field, you can reduce duplicate code by traversing each field in turn by using the loop:

{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
        <p class="help">{{ field.help_text|safe }}</p>
        {% endif %}
    </div>
{% endfor %}

Useful properties include:

{{ field.label }}
The label of the field, for example. Email address
{{ field.label_tag }}

The labels for the fields are <label> T his includes the label_suffix label_suffix. For example, label_suffix value is a colon:

<label for="id_email">Email address:</label>
{{ field.id_for_label }}
The ID that will be used id_email in the example above). I f you're building a label manually, you might want to use it label_tag For example, it is also useful if you have some inline JavaScript and want to avoid hard coding the field ID.
{{ field.value }}
The value of the field. For [email protected] .
{{ field.html_name }}
Enter the name of the field that will be used in the name field of the element. If set, the format prefix is taken into account.
{{ field.help_text }}
Any help text associated with the field.
{{ field.errors }}
Output one, which contains any validation errors that correspond to this field. Y ou can use loops to customize the representation of errors. I n this case, each object in the loop is a string with an error message. <ul class="errorlist"> {% for error in field.errors %}
{{ field.is_hidden }}
This property is whether the True form field is a hidden field, or False is a hidden field. It is not particularly useful as a template variable, but can be useful in conditional testing, such as:
{% if field.is_hidden %}
   {# Do something special #}
{% endif %}
{{ field.field }}
The instance Field in the form class that BoundField Y ou can use it to access Field such as . {{ char_field.field.max_length }}

You can also take a look

For a complete list of properties and methods, see Bound Field.

Traverse hidden and visible fields

If you want to lay out the form manually in a template instead of relying on Django's default form layout, you might want to treat the field differently from the non-hidden field. F or example, because hidden fields don't show anything, putting an error message next to the field can cause confusion for your users - so errors in those fields should be handled differently. <input type="hidden">

Django provides two ways to traverse hidden and visible fields independently on a form: hidden_fields() and visible_fields(). This is a modification to the previous example that uses both methods:

{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{% for field in form.visible_fields %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

This example does not handle any errors in hidden fields. I n general, errors in hidden fields are signs that the form has been tampered with because normal form interactions do not change them. However, you can also easily insert some error displays for these form errors.

A form template that can be reused

If your site uses the same rendering logic for forms in multiple locations, you can reduce duplication by saving the form's loop in a separate template and using the include label in other templates:

# In your form template:
{% include "form_snippet.html" %}

# In form_snippet.html:
{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

If the form object passed to the template has a different name in the context, you can use the with parameter of the tag to alias it include:

{% include "form_snippet.html" with form=comment_form %}

If you find yourself doing this often, consider creating a custom include label.

For more information: https://docs.djangoproject.com/en/3.0/topics/forms/#working-with-form-templates