HTML forms are a core component of modern websites. From Google’s simple search box to large, multi-page submissions, HTML forms are the primary means of collecting information from website visitors and users.

    The code for a basic HTML form is simple, for example:

    1. <form>
    2. <p>First Name: <input type="text" name="firstname"></p>
    3. <p>Last Name: <input type="text" name="lastname"></p>
    4. <p><input type="submit" value="Submit"></p>
    5. </form>

    The <form></form> HTML tags define the form element, and each of the form fields are contained within the form element. In this form, I have defined two text fields and a submit button. In HTML5, there are many other field element types, including email fields, date and time fields, checkboxes, radio buttons and more. I have rendered the form elements as paragraphs in this example, but it’s also common to render forms as an ordered or unordered list, or as a table with the fields filling out the rows of the table. If you were to render this form in a webpage, it would look like Figure 8-1.

    Chapter 8: Django’s Forms - 图1

    Figure 8-1: A simple HTML form.

    While creating a basic form is simple, things get more complicated once you need to use the form in a real-life situation. In a live website, you must validate the data submitted with the form. If the field is required, you must check that the field isn’t blank. If the field isn’t blank, you need to check if the data submitted is the valid data type. For example, if you are requesting an email address, you must check that a valid email address is entered.

    You must also ensure your form deals with entered data safely. A common way hackers target a website is to submit malicious program code via forms to attempt to hack into the site.

    To complicate matters further, website users expect feedback when they haven’t filled out a form correctly. So, you must also have some way of displaying errors on the form for the user to correct before allowing them to submit the form.

    Creating forms, validating data and providing feedback is a tedious process if you code it all by hand. Django is flexible in its approach to form creation and management—if you want to design your forms from scratch like this, Django doesn’t do a lot to get in your way.

    However, I don’t recommend you do this. Unless you have a special application in mind, Django has many tools and libraries that make form building much easier. In particular, Django’s Form class offers a very convenient set of class methods to take care of most of the form processing and validation for you.

    With the Form class, you create a special class that looks a lot like a Django model. Form class fields have built-in validation, depending on the field type, and an associated HTML widget.

    Let’s explore the Form class further with the Django interactive shell. From within your virtual environment, run the command:

    1. (env_myclub) ...\myclub_root> python manage.py shell

    Once the shell is running, create your SimpleForm class:

    1. 1 >>> from django import forms
    2. 2 >>> class SimpleForm(forms.Form):
    3. 3 ... firstname = forms.CharField(max_length=100)
    4. 4 ... lastname = forms.CharField(max_length=100)
    5. 5 ...
    6. 6 >>>

    Let’s have a look at what we did here:

    • Line 1. To use the Form class, we need to import the forms module from Django.
    • Line 2. We create our SimpleForm class, which inherits from Django’s forms.Form class.
    • Lines 3 and 4 are the firstname and lastname fields from our simple HTML form. Notice that the field declarations are almost identical to Django’s model field declarations.

    This is the first big plus for Django’s Form class—you don’t have to remember a new syntax for declaring form fields. But it gets better. Let’s go back to the shell:

    1. 1 >>> f = SimpleForm()
    2. 2 >>> print(f.as_p())
    3. <p><label for="id_firstname">Firstname:</label> <input type="text" name="firstname" maxlength="100" required id="id_firstname"></p>
    4. <p><label for="id_lastname">Lastname:</label> <input type="text" name="lastname" maxlength="100" required id="id_lastname"></p>
    5. >>>

    Let’s see what’s happening here:

    • Line 1 should be easy enough to follow—we have created an instance of the SimpleForm class and named the instance f.
    • Line 2 is where the Django magic happens. as_p() is a class method that formats the form as paragraphs. You can see by the output that Django has created your form elements for you without you having to write a single HTML tag!

    Django doesn’t just output HTML paragraphs—you can also get Django to output HTML for displaying your form as a list or a table. Try these out for yourself:

    1. >>> print(f.as_ul())
    2. >>> print(f.as_table())

    Note Django doesn’t generate the <form></form> element for you, nor does it generate the <ul></ul> or <table></table> elements or the submit button. This is because they are structural elements on your page, so they should remain in the template.

    Django’s Form class also handles validation for you. Let’s go back to the shell to try this out:

    1. 1 >>> f = SimpleForm({})
    2. 2 >>> f.is_valid()
    3. 3 False
    4. 4 >>> f.errors
    5. {'firstname': ['This field is required.'], 'lastname': ['This field is required.']}

    Reviewing what we did this time:

    • Line 1. We created a new instance of the SimpleForm class and passed an empty dictionary ({}) to the form.
    • Line 2. When Django created the Form class, it made firstname and lastname required by default, so when we run the is_valid() method on the empty form, it returns False.
    • Line 4. Finally, if form validation fails, Django will create a dictionary of error messages. We can access this dictionary via the errors attribute of the Form class.

    One other time-saving feature of the Form class is, when a form doesn’t validate, Django re-renders the form with the error messages added. Let’s try this out in the shell:

    1. >>> print(f.as_p())
    2. <ul class="errorlist"><li>This field is required.</li></ul>
    3. <p><label for="id_firstname">Firstname:</label> <input type="text" name="firstname" maxlength="100" required id="id_firstname"></p>
    4. <ul class="errorlist"><li>This field is required.</li></ul>
    5. <p><label for="id_lastname">Lastname:</label> <input type="text" name="lastname" maxlength="100" required id="id_lastname"></p>
    6. >>>

    You can see Django added the errors to the form as unordered lists. If you were to render this form in your browser, it would look something like Figure 8-2.

    Chapter 8: Django’s Forms - 图2

    Figure 8-2: Django’s Form class renders the error messages to the form automatically.

    Now we’ve had a look at how Django’s Form class works, let’s create our first form for the website. We will start with a simple form common to most websites—a contact form.