<span
class=
"help-block"
>
{{ error }}
</span>
</div>
{% endif %}
</form>
Take a look at the
Bootstrap docsfor more info on form controls.
Passing this error to the template is the job of the view function. Let’s take a look at the
unit tests in the
NewListTest
class. I’mgoing to use two slightly different error-handling
patterns here.
In the first case, our URL and view for new lists will optionally render the same template
as the home page, but with the addition of an error message. Here’s a unit test for that:
lists/tests/test_views.py (ch10l014).
class
NewListTest
(
TestCase
):
[
...
]
def
test_validation_errors_are_sent_back_to_home_page_template
(
self
):
response
=
self
.
client
.
post
(
'/lists/new'
,
data
=
{
'item_text'
:
''
})
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertTemplateUsed
(
response
,
'home.html'
)
expected_error
=
"You can't have an empty list item"
self
.
assertContains
(
response
,
expected_error
)
As we’re writing this test, we might get slightly offended by the
/lists/new
URL, which
we’re manually entering as a string. We’ve got a lot of URLs hardcoded in our tests, in
our views, and in our templates, which violates the DRY principle. I don’t mind a bit of
duplication in tests, but we should definitely be on the lookout for hardcoded URLs in
our views and templates, and make a note to refactor them out. But we won’t do them
straight away, because right now our application is in a broken state. We want to get
back to a working state first.
Back to our test, which is failing because the view is currently returning a 302 redirect,
rather than a “normal” 200 response:
AssertionError: 302 != 200
Let’s try calling
full_clean()
in the view:
lists/views.py.
def
new_list
(
request
):
list_
=
List
.
objects
.
create
()
item
=
Item
.
objects
.
create
(
text
=
request
.
POST
[
'item_text'
],
list
=
list_
)
item
.
full_clean
()
return
redirect
(
'/lists/
%d
/'
%
(
list_
.
id
,))
As we’re looking at the view code, we find a good candidate for a hardcoded URL to get
rid of. Let’s add that to our scratchpad:
Surfacing Model Validation Errors in the View
|
179