Skip to content

Commit 908ead4

Browse files
committed
wip on posts and db
1 parent e1eb1f9 commit 908ead4

File tree

3 files changed

+45
-39
lines changed

3 files changed

+45
-39
lines changed

chapter_post_and_database.asciidoc

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ def test_uses_home_template(self):
226226
response = self.client.get("/")
227227
self.assertTemplateUsed(response, "home.html")
228228
229-
230229
def test_can_save_a_POST_request(self):
231230
response = self.client.post("/", data={"item_text": "A new list item"})
232231
self.assertIn("A new list item", response.content.decode())
@@ -575,31 +574,36 @@ begin to see that our first cut solution really isn't going to, um, cut it:
575574
----
576575
====
577576

578-
((("", startref="DTtemplate05")))Sure
579-
enough, the functional tests return an error:
577+
((("", startref="DTtemplate05")))
578+
Sure enough, the functional tests return an error:
580579

581580
----
582581
AssertionError: '1: Buy peacock feathers' not found in ['1: Use peacock
583582
feathers to make a fly']
584583
----
585584

585+
586586
Three Strikes and Refactor
587587
~~~~~~~~~~~~~~~~~~~~~~~~~~
588588

589589

590-
((("code smell")))((("database testing", "three strikes and refactor rule", id="DTthree05")))((("three strikes and refactor rule", id="threestrikes05")))((("refactoring", id="refactor05")))Before
591-
we go further--we've got a bad
590+
((("code smell")))
591+
((("database testing", "three strikes and refactor rule", id="DTthree05")))
592+
((("three strikes and refactor rule", id="threestrikes05")))
593+
((("refactoring", id="refactor05")))
594+
Before we go further--we've got a bad
592595
__code smell__footnote:[If you've not come across the concept, a "code smell" is
593596
something about a piece of code that makes you want to rewrite it. Jeff Atwood
594597
has http://www.codinghorror.com/blog/2006/05/code-smells.html[a compilation on
595598
his blog Coding Horror]. The more experience you gain as a programmer, the more
596599
fine-tuned your nose becomes to code smells...]
597-
in this FT. We have three
598-
almost identical code blocks checking for new items in the list table. ((("Don’t Repeat Yourself (DRY)")))There's
599-
a principle called 'Don't Repeat Yourself' (DRY), which we like to apply by
600-
following the mantra 'three strikes and refactor'. You can copy and paste code
601-
once, and it may be premature to try to remove the duplication it causes, but
602-
once you get three occurrences, it's time to remove duplication.
600+
in this FT.
601+
We have three almost identical code blocks checking for new items in the list table.
602+
((("Don’t Repeat Yourself (DRY)")))There's a principle called 'Don't Repeat Yourself' (DRY),
603+
which we like to apply by following the mantra 'three strikes and refactor'.
604+
You can copy and paste code once,
605+
and it may be premature to try to remove the duplication it causes,
606+
but once you get three occurrences, it's time to remove duplication.
603607

604608

605609

@@ -888,7 +892,7 @@ The test actually gets surprisingly far:
888892
----
889893
$ pass:quotes[*python manage.py test lists*]
890894
[...]
891-
self.assertEqual(first_saved_item.text, 'The first (ever) list item')
895+
self.assertEqual(first_saved_item.text, "The first (ever) list item")
892896
AttributeError: 'Item' object has no attribute 'text'
893897
----
894898

@@ -1027,7 +1031,7 @@ response. We can do that by adding three new lines to the existing test called
10271031

10281032

10291033
[role="sourcecode"]
1030-
.lists/tests.py
1034+
.lists/tests.py (ch05l019)
10311035
====
10321036
[source,python]
10331037
----
@@ -1152,7 +1156,7 @@ class HomePageTest(TestCase):
11521156
[...]
11531157
11541158
def test_only_saves_items_when_necessary(self):
1155-
self.client.get('/')
1159+
self.client.get("/")
11561160
self.assertEqual(Item.objects.count(), 0)
11571161
----
11581162
====
@@ -1162,10 +1166,13 @@ quite a small change to the logic of the view, there are quite a few little
11621166
tweaks to the implementation in code:
11631167

11641168
[role="sourcecode"]
1165-
.lists/views.py (ch05l023)
1169+
.lists/views.py
11661170
====
11671171
[source,python]
11681172
----
1173+
from lists.models import Item
1174+
[...]
1175+
11691176
def home_page(request):
11701177
if request.method == "POST":
11711178
new_item_text = request.POST["item_text"] # <1>
@@ -1220,14 +1227,14 @@ the item in it, it should redirect back to the home page:
12201227
[source,python]
12211228
----
12221229
def test_can_save_a_POST_request(self):
1223-
response = self.client.post('/', data={'item_text': 'A new list item'})
1230+
response = self.client.post("/", data={"item_text": "A new list item"})
12241231
12251232
self.assertEqual(Item.objects.count(), 1)
12261233
new_item = Item.objects.first()
1227-
self.assertEqual(new_item.text, 'A new list item')
1234+
self.assertEqual(new_item.text, "A new list item")
12281235
12291236
self.assertEqual(response.status_code, 302)
1230-
self.assertEqual(response['location'], '/')
1237+
self.assertEqual(response["location"], "/")
12311238
----
12321239
====
12331240

@@ -1291,17 +1298,16 @@ first go, but now feels like a good time to separate out our concerns:
12911298
[source,python]
12921299
----
12931300
def test_can_save_a_POST_request(self):
1294-
self.client.post('/', data={'item_text': 'A new list item'})
1301+
self.client.post("/", data={"item_text": "A new list item"})
12951302
12961303
self.assertEqual(Item.objects.count(), 1)
12971304
new_item = Item.objects.first()
1298-
self.assertEqual(new_item.text, 'A new list item')
1299-
1305+
self.assertEqual(new_item.text, "A new list item")
13001306
13011307
def test_redirects_after_POST(self):
1302-
response = self.client.post('/', data={'item_text': 'A new list item'})
1308+
response = self.client.post("/", data={"item_text": "A new list item"})
13031309
self.assertEqual(response.status_code, 302)
1304-
self.assertEqual(response['location'], '/')
1310+
self.assertEqual(response["location"], "/")
13051311
----
13061312
====
13071313

@@ -1346,13 +1352,13 @@ class HomePageTest(TestCase):
13461352
[...]
13471353
13481354
def test_displays_all_list_items(self):
1349-
Item.objects.create(text='itemey 1')
1350-
Item.objects.create(text='itemey 2')
1355+
Item.objects.create(text="itemey 1")
1356+
Item.objects.create(text="itemey 2")
13511357
1352-
response = self.client.get('/')
1358+
response = self.client.get("/")
13531359
1354-
self.assertIn('itemey 1', response.content.decode())
1355-
self.assertIn('itemey 2', response.content.decode())
1360+
self.assertIn("itemey 1", response.content.decode())
1361+
self.assertIn("itemey 2", response.content.decode())
13561362
----
13571363
====
13581364

@@ -1361,7 +1367,7 @@ NOTE: Are you wondering about the line spacing in the test? I'm grouping
13611367
together two lines at the beginning which set up the test, one line in
13621368
the middle which actually calls the code under test, and the
13631369
assertions at the end. This isn't obligatory, but it does help see the
1364-
structure of the test. Setup, Exercise, Assert is the typical structure
1370+
structure of the test. Arrange-Act-Assert is the typical structure
13651371
for a unit test.
13661372

13671373

@@ -1405,12 +1411,12 @@ pass the items to it from our home page view:
14051411
[source,python]
14061412
----
14071413
def home_page(request):
1408-
if request.method == 'POST':
1409-
Item.objects.create(text=request.POST['item_text'])
1410-
return redirect('/')
1414+
if request.method == "POST":
1415+
Item.objects.create(text=request.POST["item_text"])
1416+
return redirect("/")
14111417
14121418
items = Item.objects.all()
1413-
return render(request, 'home.html', {'items': items})
1419+
return render(request, "home.html", {"items": items})
14141420
----
14151421
====
14161422

@@ -1465,9 +1471,9 @@ project directory:
14651471
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
14661472
14671473
DATABASES = {
1468-
'default': {
1469-
'ENGINE': 'django.db.backends.sqlite3',
1470-
'NAME': BASE_DIR / 'db.sqlite3',
1474+
"default": {
1475+
"ENGINE": "django.db.backends.sqlite3",
1476+
"NAME": BASE_DIR / "db.sqlite3",
14711477
}
14721478
}
14731479
----
@@ -1543,7 +1549,7 @@ Django template tag, `forloop.counter`, will help here:
15431549
If you try it again, you should now see the FT get to the end:
15441550

15451551
----
1546-
self.fail('Finish the test!')
1552+
self.fail("Finish the test!")
15471553
AssertionError: Finish the test!
15481554
----
15491555

tests/test_chapter_post_and_database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def test_listings_and_commands_and_output(self):
2525
assert "request.POST.get" in self.listings[views_pos].contents
2626

2727
nutemplate_pos = 77
28-
assert "{'items': items}" in self.listings[nutemplate_pos].contents
28+
assert '{"items": items}' in self.listings[nutemplate_pos].contents
2929

3030
migrate_pos = 81
3131
assert 'migrate' in self.listings[migrate_pos]

0 commit comments

Comments
 (0)