![Show Menu](styles/mobile-menu.png)
![Page Background](./../common/page-substrates/page0379.png)
Whenwe build helper functions, we can give themnames that express what we are doing
in terms of the business domain, which can actually make our code more legible, as well
as giving us the benefit of keeping all ORM calls at the model layer, and thus making
our whole application more loosely coupled.
Finally, Moving Down to the Models Layer
At the models layer, we no longer need to write isolated tests—the whole point of the
models layer is to integrate with the database, so it’s appropriate to write integrated tests:
lists/tests/test_models.py (ch19l026).
class
ListModelTest
(
TestCase
):
def
test_get_absolute_url
(
self
):
list_
=
List
.
objects
.
create
()
self
.
assertEqual
(
list_
.
get_absolute_url
(),
'/lists/
%d
/'
%
(
list_
.
id
,))
def
test_create_new_creates_list_and_first_item
(
self
):
List
.
create_new
(
first_item_text
=
'new item text'
)
new_item
=
Item
.
objects
.
first
()
self
.
assertEqual
(
new_item
.
text
,
'new item text'
)
new_list
=
List
.
objects
.
first
()
self
.
assertEqual
(
new_item
.
list
,
new_list
)
Which gives:
TypeError: create_new() got an unexpected keyword argument 'first_item_text'
And that will take us to a first cut implementation that looks like this:
lists/models.py (ch19l027).
class
List
(
models
.
Model
):
def
get_absolute_url
(
self
):
return
reverse
(
'view_list'
,
args
=
[
self
.
id
])
@staticmethod
def
create_new
(
first_item_text
):
list_
=
List
.
objects
.
create
()
Item
.
objects
.
create
(
text
=
first_item_text
,
list
=
list_
)
Notice we’ve been able to get all the way down to the models layer, driving a nice design
for the views and forms layers, and the List model still doesn’t support having an owner!
Now let’s test the case where the list should have an owner, and add:
lists/tests/test_models.py (ch19l028).
from
django.contrib.auth
import
get_user_model
User
=
get_user_model
()
[
...
]
Finally, Moving Down to the Models Layer
|
351