![Show Menu](styles/mobile-menu.png)
![Page Background](./../common/page-substrates/page0122.png)
response
=
self
.
client
.
post
(
'/lists/new'
,
data
=
{
'item_text'
:
'A new list item'
}
)
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
response
[
'location'
],
'/lists/the-only-list-in-the-world/'
)
This is another place to pay attention to trailing slashes, incidentally. It’s
/new
, with no
trailing slash. The convention I’musing is that URLs without a trailing slash are “action”
URLs which modify the database.
Try running that:
self.assertEqual(Item.objects.count(), 1)
AssertionError: 0 != 1
[...]
self.assertEqual(response.status_code, 302)
AssertionError: 404 != 302
The first failure tells us we’re not saving a new item to the database, and the second says
that, instead of returning a 302 redirect, our view is returning a 404. That’s because we
haven’t built a URL for
/lists/new
, so the
client.post
is just getting a 404 response.
Do you remember how we split this out into two tests in the last
chapter? If we only had one test that checked both the saving and the
redirect, it would have failed on the
0 != 1
failure, which would have
been much harder to debug. Ask me how I know this.
A URL and View for New List Creation
Let’s build our new URL now:
superlists/urls.py.
urlpatterns
=
patterns
(
''
,
url
(
r'^$'
,
'lists.views.home_page'
,
name
=
'home'
),
url
(
r'^lists/the-only-list-in-the-world/$'
,
'lists.views.view_list'
,
name
=
'view_list'
),
url
(
r'^lists/new$'
,
'lists.views.new_list'
,
name
=
'new_list'
),
# url(r'^admin/', include(admin.site.urls)),
)
Next we get a
ViewDoesNotExist
, so let’s fix that, in
lists/views.py
:
lists/views.py.
def
new_list
(
request
):
pass
Then we get “The view lists.views.new_list didn’t return an HttpResponse object”. (This
is getting rather familiar!)We could return a raw
HttpResponse
, but since we knowwe’ll
need a redirect, let’s borrow a line from
home_page
:
94
|
Chapter 6: Getting to the Minimum Viable Site