form
Django provides a rich framework to help create forms and process form data.
1, Foundation:
1. Overview
Django provides a series of tools and libraries to help you build forms to receive input from website visitors, and then process and respond to these inputs.
HTML form
In HTML, forms are elements in... That allow visitors to do actions such as entering text, selecting options, manipulating objects or spaces, and then send these information to the server.
Some form interface elements (text boxes or check boxes) are built into HTML. Others will be more complicated; Like pop-up date selection or allowing you to move the slider or manipulate controls, these effects are generally achieved by using JavaScript, CSS and elements in HTML forms.
Like its elements, the form must specify two things:
Where: the URL address responsible for responding to user input data
How to: the HTTP method used for data requests.
For example, the login form of Django admin contains some elements: type = "text" for user name, type = "password" for password, and type = "submit" for login button. It also contains hidden text fields that users can't see, and Django uses them to determine the next behavior.
It also tells the browser that the form data should be sent to the URL specified by the action attribute - / admin /, and the HTTP method specified by its method attribute - post should be used.
When the element is triggered, the data is sent to / admin /.
GET and POST
When processing forms, only GET and POST HTTP methods will be used.
Django's login form uses the POST method to transmit data. In this method, the browser will encapsulate the form data, encode it for transmission, and then send it to the server and receive its response.
In contrast, the GET method bundles the submitted data into a string and uses it to form a URL. The URL contains the address of the data to be sent and the data corresponding to some key values. If you do a search in the Django document, you will see this, and it will generate a similar https://docs.djangoproject.com/search/?q=forms&release=1 The URL of the.
GET and POST are often used for different purposes.
Any request that might be used to change the state of the system should use POST -- such as a request to change the database. GET should only be used for requests that do not affect the system state.
The GET method is also not suitable for the password form, because the password will appear in the URL, so it will also appear in the browser's history and the server's log, and they are all in plain text. It is also not suitable for processing large amounts of data or binary data, such as a picture. Using GET request in the management form of WEB application has a security risk: attackers can easily access the sensitive data of the system by simulating the request. The POST method can provide more control over access by using it in conjunction with other protection measures such as Django's CSRF protection.
On the other hand, the GET method is suitable for content such as web search forms, because such URL s presented as a GET request can easily be bookmarked, shared or resubmitted.
Build a form
<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>
2. Form API
Bound and unbound forms
A Form instance is either bound to a set of data or unbound.
If a set of data is bound, it can verify the data, render the form into HTML, and display the data in HTML.
If it is unbound, it cannot validate (because there is no data to validate!), but it can still render a blank form as HTML.
class Form
To create an unbound Form instance, instantiate the class:
>>> f = ContactForm()
To bind data to a Form, pass the data in the Form of a dictionary to the first parameter of your Form class constructor:
>>> data = {'subject': 'hello', ... 'message': 'Hi there', ... 'sender': 'foo@example.com', ... 'cc_myself': True} >>> f = ContactForm(data)
Form.is_bound
If you need to distinguish between bound and unbound form instances at run time, check the is of the form_ Value of the bound property:
>>> f = ContactForm() >>> f.is_bound False >>> f = ContactForm({'subject': 'hello'}) >>> f.is_bound True
3. Built in fields
form field
class Field(**kwargs)
When you create a Form class, the most important part is to define the fields of the Form. Each field has custom validation logic and other hooks.
Field.clean(value)
Although the main way you use the Field class is in the Form class, you can also instantiate them and use them directly to better understand how they work. Each Field instance has a clean() method, which receives a parameter and throws a django.core.exceptions.ValidationError exception or returns a clean value:
>>> from django import forms >>> f = forms.EmailField() >>> f.clean('foo@example.com') 'foo@example.com' >>> f.clean('invalid email address') Traceback (most recent call last): ... ValidationError: ['Enter a valid email address.']
4. Built in components
parts
Parts are Django's representation of HTML input elements. The part processes the rendering of HTML and extracts data from the GET / POST dictionary corresponding to the part.
The HTML generated by the built-in part uses HTML5 syntax, and the target is. For example, it uses Boolean attributes such as checked instead of XHTML style checked = 'checked'.
Using different widgets for a field, you can use widget parameters in the field definition. For example:
from django import forms class CommentForm(forms.Form): name = forms.CharField() url = forms.URLField() comment = forms.CharField(widget=forms.Textarea)
2, Advanced:
1. Form for model
Create form from model
ModelForm class ModelForm
If you are building a database driven application, you are likely to use forms closely related to the Django model. For example, you might have a blog comment model and you want to create a form that allows users to submit comments. In this case, it is redundant to define the field type in the form because you have already defined the field in the model.
Therefore, Django provides an auxiliary class so that you can create a Form class from a Django model.
For example:
>>> from django.forms import ModelForm >>> from myapp.models import Article # Create the form class. >>> class ArticleForm(ModelForm): ... class Meta: ... model = Article ... fields = ['pub_date', 'headline', 'content', 'reporter'] # Creating a form to add an article. >>> form = ArticleForm() # Creating a form to change an existing article. >>> article = Article.objects.get(pk=1) >>> form = ArticleForm(instance=article)
2. Integrated media
Form resources (Media class)
To render an attractive and easy-to-use web form, you need not only HTML, but also CSS style sheets. If you want to use a variety of "Web 2.0" components, you also need to include some JavaScript on each page. The exact combination of CSS and JavaScript on any given template depends on the components used on this page.
This is the source of the resource definition. Django allows you to associate different files (like style sheets and scripts) with forms and components that need these resources. For example, if you want to render DateFields with a calendar, you can customize a calendar component. This component can then be associated with the CSS and JavaScript required to render the calendar. When using the calendar component on the form, Django can identify the required CSS and JavaScript files, provide a list of file names in the form, and insert them into your web page appropriately.
Resource as static definition
The easiest way to define a resource is to define it statically. To use this method, the declaration is an internal Media class. The properties of this inner class define this requirement.
Here is an example:
from django import forms class CalendarWidget(forms.TextInput): class Media: css = { 'all': ('pretty.css',) } js = ('animations.js', 'actions.js')
3. Form set
class BaseFormSet
formset is an abstraction layer that can process multiple forms on the same page. It is best compared to grid data. We assume that you have the following form:
>>> from django import forms >>> class ArticleForm(forms.Form): ... title = forms.CharField() ... pub_date = forms.DateField()
You may want to allow users to create multiple articles at once. To create a formset of ArticleForm, you can:
>>> from django.forms import formset_factory >>> ArticleFormSet = formset_factory(ArticleForm)
You have now created a form set called ArticleFormSet. Instantiating a form set allows you to overlap the forms in the form set and display them like regular forms:
>>> formset = ArticleFormSet() >>> for form in formset: ... print(form.as_table()) <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title"></td></tr> <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date"></td></tr>
As you can see, it only displays an empty form. The number of empty forms displayed is controlled by additional parameters. By default, formset_factory() defines an additional form; The following example will create a form set class to display two blank forms:
>>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
Traversing the formset renders the forms in the order they are created. You can change this order by providing an alternative implementation for the iter() method.
The form set can also be indexed and the corresponding form returned. If you have overridden iter, you need to override getitem to make it have matching behavior.
4. Custom validation
Form and field validation
Form validation occurs when data is cleaned up. If you want to customize this process, there are various places you can change, and each place has a different purpose. There are three types of cleanup methods that run during form processing. These methods usually call is on the form_ Valid() method. There are other things that can trigger cleanup and validation (access the errors property or call full_clean() directly), but they are usually not required.
Generally speaking, any cleaning method can raise ValidationError when there is a problem with the processed data, and pass the relevant information to the ValidationError constructor. See below for best practices for raising ` ` ValidationError '. If ValidationError is not raised, the method should return the cleaned (normalized) data as a Python object.
Most validation can be done using validators, a reusable accessibility feature. A validator is a function (or callable object) that accepts only one parameter and raises a ValidationError when an invalid input occurs. Validator in field to_ The Python and validate methods run after they are called.
Provide a descriptive error code for the constructor:
Good
ValidationError(_('Invalid value'), code='invalid')
Bad
ValidationError(_('Invalid value'))
Do not force variables into the information; params parameters using placeholders and constructors:
Good
ValidationError( _('Invalid value: %(value)s'), params={'value': '42'}, )
Bad
ValidationError(_('Invalid value: %s') % value)
Use mapping keys instead of position formatting. In this way, the variables can be arranged in any order or completely omitted when rewriting the information:
Good
ValidationError( _('Invalid value: %(value)s'), params={'value': '42'}, )
Bad
ValidationError( _('Invalid value: %s'), params=('42',), )
Wrap the information with gettext to enable translation:
Good
ValidationError(_('Invalid value'))
Bad
ValidationError('Invalid value')
Put it together:
raise ValidationError( _('Invalid value: %(value)s'), code='invalid', params={'value': '42'}, )