Compare commits

..

10 Commits

5 changed files with 94 additions and 27 deletions

View File

@ -4,13 +4,13 @@
</head> </head>
<body> <body>
<h1>Your To-Do list</h1> <h1>Your To-Do list</h1>
<form method="POST" action="/lists/new"> <form method="POST" action="/lists/{{ list.id }}/add_item">
<input name="item_text" id="id_new_item" placeholder="Enter a to-do item" /> <input name="item_text" id="id_new_item" placeholder="Enter a to-do item" />
{% csrf_token %} {% csrf_token %}
</form> </form>
<table id="id_list_table"> <table id="id_list_table">
{% for item in items %} {% for item in list.item_set.all %}
<tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr> <tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -1,3 +1,4 @@
from django.http import response
from django.test import TestCase from django.test import TestCase
from lists.models import Item, List from lists.models import Item, List
@ -8,10 +9,6 @@ class HomePageTest(TestCase):
response = self.client.get('/') response = self.client.get('/')
self.assertTemplateUsed(response, 'home.html') self.assertTemplateUsed(response, 'home.html')
def test_only_saves_items_when_necessary(self):
self.client.get('/')
self.assertEqual(Item.objects.count(), 0)
class NewListTest(TestCase): class NewListTest(TestCase):
def test_can_save_a_POST_request(self): def test_can_save_a_POST_request(self):
@ -22,22 +19,65 @@ class NewListTest(TestCase):
def test_redirects_after_POST(self): def test_redirects_after_POST(self):
response = self.client.post('/lists/new', data={'item_text': 'A new list item'}) response = self.client.post('/lists/new', data={'item_text': 'A new list item'})
self.assertRedirects(response=response, expected_url='/lists/the-only-list-in-the-world/') new_list = List.objects.first()
self.assertRedirects(response=response, expected_url=f'/lists/{new_list.id}/')
class NewItemTest(TestCase):
def test_can_save_a_POST_request_to_an_existing_list(self):
other_list = List.objects.create()
correct_list = List.objects.create()
self.client.post(
f'/lists/{correct_list.id}/add_item',
data={'item_text': 'A new item for an existing list'}
)
self.assertEqual(Item.objects.count(), 1)
new_item = Item.objects.first()
self.assertEqual(new_item.text, 'A new item for an existing list')
self.assertEqual(new_item.list, correct_list)
def test_redirects_to_list_view(self):
other_list = List.objects.create()
correct_list = List.objects.create()
response = self.client.post(
f'/lists/{correct_list.id}/add_item',
data={'item_text': 'A new item for an existing list'}
)
self.assertRedirects(
response=response,
expected_url=f'/lists/{correct_list.id}/')
class ListViewTest(TestCase): class ListViewTest(TestCase):
def test_uses_list_template(self): def test_uses_list_template(self):
response = self.client.get('/lists/the-only-list-in-the-world/') list_ = List.objects.create()
response = self.client.get(f'/lists/{list_.id}/')
self.assertTemplateUsed(response=response, template_name='list.html') self.assertTemplateUsed(response=response, template_name='list.html')
def test_displays_all_items(self): def test_displays_only_items_for_that_list(self):
Item.objects.create(text="itemey 1") correct_list = List.objects.create()
Item.objects.create(text="itemey 2") Item.objects.create(text="itemey 1", list=correct_list)
Item.objects.create(text="itemey 2", list=correct_list)
other_list = List.objects.create()
Item.objects.create(text="other list item 1", list=other_list)
Item.objects.create(text="other list item 2", list=other_list)
response = self.client.get('/lists/the-only-list-in-the-world/') response = self.client.get(f'/lists/{correct_list.id}/')
self.assertContains(response, 'itemey 1') self.assertContains(response, 'itemey 1')
self.assertContains(response, 'itemey 2') self.assertContains(response, 'itemey 2')
self.assertNotContains(response=response, text='other list item 1')
self.assertNotContains(response=response, text='other list item 2')
def test_passes_correct_list_to_template(self):
other_list = List.objects.create()
correct_list = List.objects.create()
response = self.client.get(f'/lists/{correct_list.id}/')
self.assertEqual(response.context['list'], correct_list)
class ListAndItemModelsTest(TestCase): class ListAndItemModelsTest(TestCase):

23
src/lists/urls.py 100644
View File

@ -0,0 +1,23 @@
"""superlists URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from lists import views
urlpatterns = [
url(r'^lists/new$', views.new_list, name='new_list'),
url(r'^lists/(\d+)/$', views.view_list, name='view_list'),
url(r'^lists/(\d+)/add_item$', views.add_item, name='add_item'),
]

View File

@ -1,17 +1,21 @@
from typing import Text
from django.http import request
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from lists.models import Item from lists.models import Item, List
# Create your views here # Create your views here
def home_page(request): def home_page(request):
return render(request=request, template_name='home.html') return render(request=request, template_name='home.html')
def view_list(request): def view_list(request, list_id):
items = Item.objects.all() list_ = List.objects.get(id=list_id)
return render(request, 'list.html', {'items': items}) return render(request, 'list.html', {'list': list_})
def new_list(request): def new_list(request):
Item.objects.create(text=request.POST['item_text']) list_ = List.objects.create()
return redirect('/lists/the-only-list-in-the-world/') Item.objects.create(text=request.POST['item_text'], list=list_)
return redirect(f'/lists/{list_.id}/')
def add_item(request, list_id):
list_ = List.objects.get(id=list_id)
Item.objects.create(text=request.POST['item_text'], list=list_)
return redirect(f'/lists/{list_.id}/')

View File

@ -13,11 +13,11 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include 1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
""" """
from django.conf.urls import url from django.conf.urls import include, url
from lists import views from lists import views as list_views
from lists import urls as list_urls
urlpatterns = [ urlpatterns = [
url(r'^$', views.home_page, name='home'), url(r'^$', list_views.home_page, name='home'),
url(r'^lists/new$', views.new_list, name='new_list'), url(r'^lists/', include(list_urls)),
url(r'^lists/the-only-list-in-the-world/$', views.view_list, name='view_list'),
] ]