无法在 Django 中包含来自我的应用程序的网址

Cannot include urls from my app in django

我正在使用 Python 关注 TDD web 开发以学习 Django。它基于 Django 1.8,但我试图在 Django 1.11 上遵循它。自1.8以来似乎有太多变化。在作者告诉我为我的应用程序制作一个单独的 urls.py 文件之前,我的应用程序(列表)运行良好。现在,所有测试都失败并出现 404 错误。

我的urls.py是

from django.conf.urls import url, include
from lists import views as list_views

urlpatterns = [
    url(r'^$', list_views.home_page, name='home'),
    url(r'^lists/', include('lists.urls')),
]

和我的 lists/urls.py

from django.conf.urls import url
from lists import views as list_views

app_name = 'lists'
urlpatterns = [
    url(r'^lists/(\d+)/$', list_views.view_list, name = 'view_list'),
    url(r'^lists/(\d+)/add_item$', list_views.add_item, name = 'add_item'),
    url(r'^lists/new$', list_views.new_list, name = 'new_list'),
]

这些是我产生错误的测试

class ListAndItemModelsTest(TestCase):

    def test_saving_and_retrieving_items(self):
        list_ = List()
        list_.save()

        first_item = Item()
        first_item.text = 'The first (ever) list item'
        first_item.list = list_
        first_item.save()

        second_item = Item()
        second_item.text = 'Item the second'
        second_item.list = list_
        second_item.save()

        saved_list = List.objects.first()
        self.assertEqual(saved_list, list_)

        saved_items = Item.objects.all()
        self.assertEqual(saved_items.count(), 2)

        first_saved_item = saved_items[0]
        second_saved_item = saved_items[1]
        self.assertEqual(first_saved_item.text, 'The first (ever) list item')
        self.assertEqual(first_saved_item.list, list_)
        self.assertEqual(second_saved_item.text, 'Item the second')
        self.assertEqual(second_saved_item.list, list_)

class ListViewTest(TestCase):

    def test_uses_list_template(self):
        list_ = List.objects.create()
        response = self.client.get('/lists/%d/' % (list_.id,))
        self.assertTemplateUsed(response, 'list.html')

    def test_displays_only_items_for_that_list(self):
        correct_list = List.objects.create()
        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/%d/' % (correct_list.id,))

        self.assertContains(response, 'itemey 1')
        self.assertContains(response, 'itemey 2')
        self.assertNotContains(response, 'other list item 1')
        self.assertNotContains(response, '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.post('/lists/%d/' % (correct_list.id,))
        self.assertEqual(response.context['list'], correct_list)

class NewListTest(TestCase):

    def test_saving_a_POST_request(self):

        response = self.client.post(
                '/lists/new',
                data = {'item_text': 'A new list item'}
            )

        self.assertEqual(Item.objects.count(), 1)
        new_item = Item.objects.first()
        self.assertEqual(new_item.text, 'A new list item')

    def test_redirects_after_POST(self):

        response = self.client.post(
                '/lists/new',
                data = {'item_text': 'A new list item'}
            )

        new_list = List.objects.first()

        self.assertRedirects(response, '/lists/%d/' % (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(
                '/lists/%d/add_item' % (correct_list.id,),
                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(
                '/lists/%d/add_item' % (correct_list.id,),
                data = {'item_text': 'A new item for an existing list'}
            )

        self.assertRedirects(response, '/lists/%d/' % (correct_list.id,))

这些错误发生在我 运行 我的测试中,

ERROR: test_passes_correct_list_to_template (lists.tests.ListViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abhi/Development/DjangoDev/superlists/lists/tests.py", line 78, in test_passes_correct_list_to_template
    self.assertEqual(response.context['list'], correct_list)
  File "/home/abhi/.local/lib/python3.5/site-packages/django/template/context.py", line 87, in __getitem__
    raise KeyError(key)
KeyError: 'list'

======================================================================
ERROR: test_redirects_after_POST (lists.tests.NewListTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abhi/Development/DjangoDev/superlists/lists/tests.py", line 102, in test_redirects_after_POST
    self.assertRedirects(response, '/lists/%d/' % (new_list.id,))
AttributeError: 'NoneType' object has no attribute 'id'

======================================================================
FAIL: test_displays_only_items_for_that_list (lists.tests.ListViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abhi/Development/DjangoDev/superlists/lists/tests.py", line 69, in test_displays_only_items_for_that_list
    self.assertContains(response, 'itemey 1')
  File "/home/abhi/.local/lib/python3.5/site-packages/django/test/testcases.py", line 385, in assertContains
    response, text, status_code, msg_prefix, html)
  File "/home/abhi/.local/lib/python3.5/site-packages/django/test/testcases.py", line 357, in _assert_contains
    " (expected %d)" % (response.status_code, status_code)
AssertionError: 404 != 200 : Couldn't retrieve content: Response code was 404 (expected 200)

======================================================================
FAIL: test_uses_list_template (lists.tests.ListViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abhi/Development/DjangoDev/superlists/lists/tests.py", line 56, in test_uses_list_template
    self.assertTemplateUsed(response, 'list.html')
  File "/home/abhi/.local/lib/python3.5/site-packages/django/test/testcases.py", line 578, in assertTemplateUsed
    self.fail(msg_prefix + "No templates used to render the response")
AssertionError: No templates used to render the response

======================================================================
FAIL: test_can_save_a_POST_request_to_an_existing_list (lists.tests.NewItemTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abhi/Development/DjangoDev/superlists/lists/tests.py", line 115, in test_can_save_a_POST_request_to_an_existing_list
    self.assertEqual(Item.objects.count(), 1)
AssertionError: 0 != 1

======================================================================
FAIL: test_redirects_to_list_view (lists.tests.NewItemTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abhi/Development/DjangoDev/superlists/lists/tests.py", line 129, in test_redirects_to_list_view
    self.assertRedirects(response, '/lists/%d/' % (correct_list.id,))
  File "/home/abhi/.local/lib/python3.5/site-packages/django/test/testcases.py", line 294, in assertRedirects
    % (response.status_code, status_code)
AssertionError: 404 != 302 : Response didn't redirect as expected: Response code was 404 (expected 302)

======================================================================
FAIL: test_saving_a_POST_request (lists.tests.NewListTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/abhi/Development/DjangoDev/superlists/lists/tests.py", line 89, in test_saving_a_POST_request
    self.assertEqual(Item.objects.count(), 1)
AssertionError: 0 != 1

感谢任何帮助。谢谢!

您可以尝试删除 url 模式中的 lists,正如您在主要 urls.py 中提供的那样:

urlpatterns = [
    url(r'^(\d+)/$', list_views.view_list, name = 'view_list'),
    url(r'^(\d+)/add_item$', list_views.add_item, name = 'add_item'),
    url(r'^new$', list_views.new_list, name = 'new_list'),
]

您需要覆盖来自

的测试
.get('/lists/

双名单

.get('/lists/lists/
#            ^^^^^^

或使用 reverse 的最佳方式,例如:

from django.urls import reverse
# Some your code
# instead of response = self.client.get('/lists/%d/' % (list_.id,))
url = reverse('lists:view_list', args=[list_.id])
response = self.client.get(url)