May 14, 2021 Django
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.
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:
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.
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
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:
It's possible to write code to do it all manually, but Django's can take care of it all for you.
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.
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.
When rendering objects in Django, it is common to:
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:
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.
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.
We already know what we want HTML forms to look like. Our starting point in Django is:
the forms.pyfrom 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:
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.
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.pyfrom 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.
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.
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.
The difference between bound and unbound forms is important:
The form'is_bound properties tell you if the form is bound to data.
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.pyfrom 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.
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
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.pyfrom 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.
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>
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:
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.
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>
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.
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 }}
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 }}
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 }}
[email protected]
.
{{ field.html_name }}
{{ field.help_text }}
{{ field.errors }}
<ul class="errorlist">
{% for error in field.errors %}
{{ field.is_hidden }}
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 }}
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.
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.
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