Background Image
Table of Contents Table of Contents
Previous Page  207 / 478 Next Page
Information
Show Menu
Previous Page 207 / 478 Next Page
Page Background

<span

class=

"help-block"

>

{{ error }}

</span>

</div>

{% endif %}

</form>

Take a look at the

Bootstrap docs

for 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