![Show Menu](styles/mobile-menu.png)
![Page Background](./../common/page-substrates/page0248.png)
def
test_form_validation_for_duplicate_items
(
self
):
list_
=
List
.
objects
.
create
()
Item
.
objects
.
create
(
list
=
list_
,
text
=
'no twins!'
)
form
=
ExistingListItemForm
(
for_list
=
list_
,
data
=
{
'text'
:
'no twins!'
})
self
.
assertFalse
(
form
.
is_valid
())
self
.
assertEqual
(
form
.
errors
[
'text'
], [
DUPLICATE_ITEM_ERROR
])
We can iterate through a few TDD cycles (I won’t show them all, but I’m sure you’ll do
them, right? Remember, theGoat sees all.) until we get a formwith a customconstructor,
which just ignores its
for_list
argument:
lists/forms.py (ch09l071).
DUPLICATE_ITEM_ERROR
=
"You've already got this in your list"
[
...
]
class
ExistingListItemForm
(
forms
.
models
.
ModelForm
):
def
__init__
(
self
,
for_list
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
Gives:
ValueError: ModelForm has no model class specified.
Now let’s see if making it inherit from our existing form helps:
lists/forms.py (ch09l072).
class
ExistingListItemForm
(
ItemForm
):
def
__init__
(
self
,
for_list
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
That takes us down to just one failure:
FAIL: test_form_validation_for_duplicate_items
(lists.tests.test_forms.ExistingListItemFormTest)
self.assertFalse(form.is_valid())
AssertionError: True is not false
The next step requires a little knowledge of Django’s internals, but you can read up on
it in the Django docs on
model validationand
form validation .Django uses a method called
validate_unique
, both on forms and models, and we can
use both, in conjunction with the
instance
attribute:
lists/forms.py.
from
django.core.exceptions
import
ValidationError
[
...
]
class
ExistingListItemForm
(
ItemForm
):
def
__init__
(
self
,
for_list
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
self
.
instance
.
list
=
for_list
def
validate_unique
(
self
):
try
:
220
|
Chapter 12: More Advanced Forms