Compare commits

..

11 Commits

9 changed files with 116 additions and 53 deletions

3
.gitignore vendored
View File

@ -1,2 +1 @@
.vscode .vscode
**/migrations/**

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-11-10 12:36
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Item',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField(default='')),
],
),
]

View File

@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-11-11 03:40
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('lists', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='List',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
),
migrations.AddField(
model_name='item',
name='list',
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='lists.List'),
),
]

View File

@ -1,4 +1,8 @@
from django.db import models from django.db import models
class List(models.Model):
pass
class Item(models.Model): class Item(models.Model):
text = models.TextField(default='') text = models.TextField(default='')
list = models.ForeignKey(List, default=None)

View File

@ -4,15 +4,9 @@
</head> </head>
<body> <body>
<h1>Your To-Do list</h1> <h1>Your To-Do list</h1>
<form method="POST"> <form method="POST" action="/lists/new">
<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">
{% for item in items %}
<tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr>
{% endfor %}
</table>
</body> </body>
</html> </html>

View File

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

View File

@ -1,74 +1,70 @@
from typing import Text
from django.http import response
from django.test import TestCase from django.test import TestCase
from django.urls import resolve
from django.http import HttpRequest
from lists.views import home_page from lists.models import Item, List
from lists.models import Item
class HomePageTest(TestCase): class HomePageTest(TestCase):
def test_root_url_resolves_to_home_page_view(self):
found = resolve('/')
self.assertEqual(found.func, home_page)
def test_uses_home_template(self): def test_uses_home_template(self):
response = self.client.get('/') response = self.client.get('/')
self.assertTemplateUsed(response, 'home.html') self.assertTemplateUsed(response, 'home.html')
def test_can_save_a_POST_request(self): def test_only_saves_items_when_necessary(self):
self.client.post('/', data={'item_text': 'A new list item'}) self.client.get('/')
self.assertEqual(Item.objects.count(), 0)
class NewListTest(TestCase):
def test_can_save_a_POST_request(self):
self.client.post('/lists/new', data={'item_text': 'A new list item'})
self.assertEqual(Item.objects.count(), 1) self.assertEqual(Item.objects.count(), 1)
new_item = Item.objects.first() new_item = Item.objects.first()
self.assertEqual(new_item.text, 'A new list item') self.assertEqual(new_item.text, 'A new list item')
def test_redirects_after_POST(self): def test_redirects_after_POST(self):
response = self.client.post('/', 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/')
self.assertEqual(response.status_code, 302)
self.assertEqual(response['location'], '/lists/the-only-list-in-the-world')
def test_only_saves_items_when_necessary(self):
self.client.get('/')
self.assertEqual(Item.objects.count(), 0)
def test_displays_all_list_items(self):
Item.objects.create(text="itemey 1")
Item.objects.create(text="itemey 2")
response = self.client.get('/')
self.assertIn('itemey 1', response.content.decode())
self.assertIn('itemey 2', response.content.decode())
class ListViewTest(TestCase): class ListViewTest(TestCase):
def test_uses_list_template(self):
response = self.client.get('/lists/the-only-list-in-the-world/')
self.assertTemplateUsed(response=response, template_name='list.html')
def test_displays_all_items(self): def test_displays_all_items(self):
Item.objects.create(text="itemey 1") Item.objects.create(text="itemey 1")
Item.objects.create(text="itemey 2") Item.objects.create(text="itemey 2")
response = self.client.get('/lists/the-only-list-in-the-world') response = self.client.get('/lists/the-only-list-in-the-world/')
self.assertIn('itemey 1', response.content.decode()) self.assertContains(response, 'itemey 1')
self.assertIn('itemey 2', response.content.decode()) self.assertContains(response, 'itemey 2')
class ItemModelTest(TestCase): class ListAndItemModelsTest(TestCase):
def test_saving_and_retrieving_items(self): def test_saving_and_retrieving_items(self):
list_ = List()
list_.save()
first_item = Item() # Create an object first_item = Item() # Create an object
first_item.text = 'The first (ever) list item' # Assign attributes first_item.text = 'The first (ever) list item' # Assign attributes
first_item.list = list_
first_item.save() # Calling .save() function first_item.save() # Calling .save() function
second_item = Item() second_item = Item()
second_item.text = 'Item the second' second_item.text = 'Item the second'
second_item.list = list_
second_item.save() second_item.save()
saved_list = List.objects.first()
self.assertEqual(saved_list, list_)
saved_items = Item.objects.all() saved_items = Item.objects.all()
self.assertEqual(saved_items.count(), 2) self.assertEqual(saved_items.count(), 2)
first_saved_item = saved_items[0] first_saved_item = saved_items[0]
second_saved_item = saved_items[1] second_saved_item = saved_items[1]
self.assertEqual(first_saved_item.text, 'The first (ever) list item') self.assertEqual(first_saved_item.text, 'The first (ever) list item')
self.assertEqual(second_saved_item.text, 'Item the second') self.assertEqual(first_saved_item.list, list_)
self.assertEqual(second_saved_item.text, 'Item the second')
self.assertEqual(second_saved_item.list, list_)

View File

@ -1,16 +1,17 @@
from django.http.request import HttpRequest from typing import Text
from django.http.response import HttpResponse 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
# Create your views here # Create your views here
def home_page(request): def home_page(request):
if request.method == 'POST': return render(request=request, template_name='home.html')
Item.objects.create(text=request.POST['item_text'])
return redirect('/lists/the-only-list-in-the-world')
items = Item.objects.all() # get objects from database (model) def view_list(request):
return render(request=request, items = Item.objects.all()
template_name='home.html', return render(request, 'list.html', {'items': items})
context={'items': items}) # pass items into template using render
def new_list(request):
Item.objects.create(text=request.POST['item_text'])
return redirect('/lists/the-only-list-in-the-world/')

View File

@ -18,5 +18,6 @@ from lists import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.home_page, name='home'), url(r'^$', views.home_page, name='home'),
url(r'^lists/new$', views.new_list, name='new_list'),
url(r'^lists/the-only-list-in-the-world/$', views.view_list, name='view_list'), url(r'^lists/the-only-list-in-the-world/$', views.view_list, name='view_list'),
] ]