![Show Menu](styles/mobile-menu.png)
![Page Background](./../common/page-substrates/page0224.png)
from
lists.models
import
Item
class
ItemForm
(
forms
.
models
.
ModelForm
):
class
Meta
:
model
=
Item
fields
=
(
'text'
,)
In
Meta
we specify which model the form is for, and which fields we want it to use.
ModelForm
s do all sorts of smart stuff, like assigning sensible HTML form input types
to different types of field, and applying default validation. Check out the
docsfor more
info.
We now have some different-looking form HTML:
AssertionError: 'placeholder="Enter a to-do item"' not found in '<p><label
for="id_text">Text:</label> <textarea cols="40" id="id_text" name="text"
rows="10">\r\n</textarea></p>'
It’s lost our placeholder and CSS class. But you can also see that it’s using
name="text"
instead of
name="item_text"
. We can probably live with that. But it’s using a
textar
ea
instead of a normal input, and that’s not the UI we want for our app. Thankfully, you
can override widgets for
ModelForm
fields, similarly to the way we did it with the normal
form:
lists/forms.py.
class
ItemForm
(
forms
.
models
.
ModelForm
):
class
Meta
:
model
=
Item
fields
=
(
'text'
,)
widgets
=
{
'text'
:
forms
.
fields
.
TextInput
(
attrs
=
{
'placeholder'
:
'Enter a to-do item'
,
'class'
:
'form-control input-lg'
,
}),
}
That gets the test passing.
Testing and Customising Form Validation
Now let’s see if the
ModelForm
has picked up the same validation rules which we defined
on the model. We’ll also learn how to pass data into the form, as if it came from the user:
lists/tests/test_forms.py (ch11l008).
def
test_form_validation_for_blank_items
(
self
):
form
=
ItemForm
(
data
=
{
'text'
:
''
})
form
.
save
()
That gives us:
ValueError: The Item could not be created because the data didn't validate.
196
|
Chapter 11: A Simple Form