What You'll Learn in This Hour |
Forms are a basic element of any website. HTML forms are used to collect input from users. This input can be used to change data in the database, configure settings, send emails, and perform various other tasks.
Django provides a useful library to help you create and handle forms. The Django forms library is intended to handle HTML form display, data processing, and redisplay. In this hour, you will learn how to create forms and display them in your HTML views. We won't actually gather any input from the forms in this hour; that topic is covered in the next hour.
Before starting this hour, you need to understand a few terms:
Model: We covered models earlier. You should remember that a model is an object-definition with several fields defined that define attributes of the object.
Form: In this hour, form refers to a Django Form class that is used to render HTML forms.
Field: Both models and forms have Field objects. The Field objects for models and forms are similar and are somewhat related, but they are not the same. Appendix B, "Django Form Field Objects," contains a table that maps Model Fields to Form Fields.
Widget: A Widget is an object that renders to an HTML form element. Each Form Field has an associated Widget object that is used when rendering the Form as HTML. For example, a CharField Widget renders to an HTML text input element. Appendix B lists the Widget objects.
Watch Out!
Currently, the two form libraries are forms and newforms. The forms library is old, so it isn't covered in this book. The Django project suggests that you import the newforms library as forms to maintain backward compatibility. Perhaps the Django developers intend to remove the old forms library and replace it with newforms. In this book, however, I always import the newforms library using the following import statement:
from django import newforms as forms
When I refer to the forms library, I am really referring to the newforms library.
You can define forms in Django by creating a class that inherits the Form class and then defining Field objects as members of the form. For example, to create an address book form that includes name, address, and email fields, you would use the following class definition:
from django import newforms as forms class AddressForm(forms.Form): name = forms.CharField() address = forms.CharField() email = forms.EmailField()
After the form has been created, you can create instances of the form by calling this constructor:
adr = AddressForm()
The following sections describe the different fields you can use when defining forms, how to create bound and unbound instances of the forms, and how to override built-in form methods.
You can add several different types of fields to forms. The advantage of different types of fields is that the form can more closely match the data types that will be put into it and validated.
Several Field objects are available in the forms package. The following is a list of the Field objects and their uses. For more information about each Field object, see Appendix B.
The BooleanField object is used to add true/false values. It renders a check box.
The CharField object is used for most textual input. It renders a text box.
The ChoiceField object is used to select an item from a list. It renders a select box.
The DateField object is used to specify a date. It renders a text box.
The DateTimeField object is used to specify a date/time. It renders a text box.
The DecimalField object is used to specify numeric data in the form of a decimal value. It renders a text box.
The EmailField object is used to specify an email address. It renders a text box.
The FileField object is used to specify a file. It renders a file upload.
The ImageField object is used to specify an image file. It renders a file upload.
The IntegerField object is used to specify numeric data in the form of an integer value. It renders a text box.
The IPAddressField object is used to specify an IPv4 address. It renders a text box.
The MultipleChoiceField object is used to select multiple items from a list. It renders a multiple-select box.
The NullBooleanField object is used to select a true/false/none value. It renders a null Boolean select.
The RegexField object is used to specify that you want a specific regular expression as the input. It renders a text box.
The TimeField object is used to specify a time. It renders a text box.
The URLField object is used to specify a valid URL. It renders a text box.
Each Field object has the following core field arguments available when you define the form:
The required argument can be set to True or False; it defaults to True. If required is set to False, no value is required when creating or validating the form.
The label argument allows you to specify a textual label that is displayed when the form is rendered. If label is not specified, the name of the field is used.
The initial argument allows you to specify an initial value for the field. initial is used only with unbound forms.
The widget argument allows you to specify a Widget object to use when rendering the field. The Widget object determines what HTML element is used in the form when it is rendered. For more details about the types of Widget objects you can assign to fields, see Appendix B.
The help_text argument allows you to specify a string that is displayed next to the field when the field is rendered.
The following example shows a simple Field definition that uses the core field arguments:
desc = forms.CharField(required=False, label='Description', widget=forms.Textarea(), help_text='Your description here.')
You can create two different types of form instances, depending on what you need from the form. You can create forms that are either bound or unbound to data. A bound form is a form that contains data bound to each element in the form. An unbound form is a blank form that contains no data values for the elements in the form.
A form that is unbound to data cannot do validation, but it can still render the form so that it can be displayed as HTML. To create an unbounded instance of a form, you simply need to call the Form constructor. The following example creates an unbound form:
adr = AddressForm()
A form that is bound to data can validate that data as well as render it to be displayed as HTML. To create a bound instance of a form, you need a dictionary. The dictionary's keys need to match the names of the fields you specified when you defined the form. The values need to be valid for the Field object that the key specifies. The following example shows how to create a form that is bound to a dataset:
from django import newforms as forms class AddressForm(forms.Form): name = forms.CharField() address = forms.CharField() email = forms.EmailField() . . . dset = {'name': 'Surfs Up', 'address': 'Somewhere Wet', 'email': 'blue@ocean.waves'} adr = AddressForm(dset)
When the AddressForm instance is created, it is bound to the data in dset.
Watch Out!
Bound forms should be considered immutable. You cannot change the data after the form has been created. To change the data, you need to create another instance of the form.
By the Way
To determine whether a form instance is bound, you can access the is_bound attribute of the Form object. For the preceding example, the following line of code would evaluate to True:
adr.is_bound