首页 > 代码库 > 使用TDD理解views.py与urls.py的关系

使用TDD理解views.py与urls.py的关系

首先必须对MVC的概念有初步的认识,django也遵循这样一套规范,views.py相当于视图函数,是整个架构中的处理引擎,而urls.py的作用就是将用户请求送入这样的引擎。

项目结构:

技术分享

 

urls.py:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    # Examples:
    #url(r‘^$‘, ‘mysite.views.home‘, name=‘home‘),
    # url(r‘^blog/‘, include(‘blog.urls‘)),

    url(r^admin/, include(admin.site.urls)),
]

 

views.py:

from django.shortcuts import render

 

单元测试代码片段:tests.py

from django.test import TestCase
from django.core.urlresolvers import resolve
from list.views import home_page

class testcase(TestCase):
    def test_resolve(self):
        found = resolve("/")
        self.assertEqual(found.func,home_page)

 

使用命令执行单元测试:python3 manage.py test

输出如下:

 1 reating test database for alias default...
 2 E
 3 ======================================================================
 4 ERROR: list.tests (unittest.loader.ModuleImportFailure)
 5 ----------------------------------------------------------------------
 6 Traceback (most recent call last):
 7   File "/usr/lib/python3.4/unittest/case.py", line 58, in testPartExecutor
 8     yield
 9   File "/usr/lib/python3.4/unittest/case.py", line 577, in run
10     testMethod()
11   File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure
12     raise exception
13 ImportError: Failed to import test module: list.tests
14 Traceback (most recent call last):
15   File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests
16     module = self._get_module_from_name(name)
17   File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name
18     __import__(name)
19   File "/home/django/mysite3/list/tests.py", line 3, in <module>
20     from list.views import home_page
21 ImportError: cannot import name home_page
22 
23 
24 ----------------------------------------------------------------------
25 Ran 1 test in 0.001s
26 
27 FAILED (errors=1)
28 Destroying test database for alias default...

根据提示,20~21行显示没有home_page 对象,所以改写views.py,如下:

 1 root@Pad:/home/django/mysite3# python3 manage.py test
 2 Creating test database for alias default...
 3 E
 4 ======================================================================
 5 ERROR: test_resolve (list.tests.testcase)
 6 ----------------------------------------------------------------------
 7 Traceback (most recent call last):
 8   File "/home/django/mysite3/list/tests.py", line 7, in test_resolve
 9     found = resolve("/")
10   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 522, in resolve
11     return get_resolver(urlconf).resolve(path)
12   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 388, in resolve
13     raise Resolver404({tried: tried, path: new_path})
14 django.core.urlresolvers.Resolver404: {path: ‘‘, tried: [[<RegexURLResolver <RegexURLPattern list> (admin:admin) ^admin/>]]}
15 
16 ----------------------------------------------------------------------
17 Ran 1 test in 0.005s
18 
19 FAILED (errors=1)
20 Destroying test database for alias default...

根据19行提示,路径问题,没有正确将请求如果到指定的应用,改写urls.py:

 1 from django.conf.urls import include, url
 2 from django.contrib import admin
 3 
 4 urlpatterns = [
 5     # Examples:
 6     url(r^$, mysite.views.home, name=home),
 7     # url(r‘^blog/‘, include(‘blog.urls‘)),
 8 
 9     url(r^admin/, include(admin.site.urls)),
10 ]

进行单元测试:

 1 root@Pad:/home/django/mysite3# python3 manage.py test
 2 Creating test database for alias default...
 3 E
 4 ======================================================================
 5 ERROR: test_resolve (list.tests.testcase)
 6 ----------------------------------------------------------------------
 7 Traceback (most recent call last):
 8   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 106, in get_callable
 9     mod = import_module(mod_name)
10   File "/usr/lib/python3.4/importlib/__init__.py", line 109, in import_module
11     return _bootstrap._gcd_import(name[level:], package, level)
12   File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
13   File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
14   File "<frozen importlib._bootstrap>", line 2212, in _find_and_load_unlocked
15   File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
16   File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
17   File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
18   File "<frozen importlib._bootstrap>", line 2224, in _find_and_load_unlocked
19 ImportError: No module named mysite
20 
21 During handling of the above exception, another exception occurred:
22 
23 Traceback (most recent call last):
24   File "/home/django/mysite3/list/tests.py", line 7, in test_resolve
25     found = resolve("/")
26   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 522, in resolve
27     return get_resolver(urlconf).resolve(path)
28   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 368, in resolve
29     sub_match = pattern.resolve(new_path)
30   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 240, in resolve
31     return ResolverMatch(self.callback, args, kwargs, self.name)
32   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 247, in callback
33     self._callback = get_callable(self._callback_str)
34   File "/usr/lib/python3.4/functools.py", line 448, in wrapper
35     result = user_function(*args, **kwds)
36   File "/usr/local/lib/python3.4/dist-packages/django/core/urlresolvers.py", line 112, in get_callable
37     if submod and not module_has_submodule(import_module(parentmod), submod):
38   File "/usr/lib/python3.4/importlib/__init__.py", line 109, in import_module
39     return _bootstrap._gcd_import(name[level:], package, level)
40   File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
41   File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
42   File "<frozen importlib._bootstrap>", line 2224, in _find_and_load_unlocked
43 ImportError: No module named mysite
44 
45 ----------------------------------------------------------------------
46 Ran 1 test in 0.031s
47 
48 FAILED (errors=1)
49 Destroying test database for alias default...

43行提示,不是正确的module,根据时间环境修改urls.py如下:

 1 from django.conf.urls import include, url
 2 from django.contrib import admin
 3 
 4 urlpatterns = [
 5     # Examples:
 6     url(r^$, list.views.home_page, name=home),
 7     # url(r‘^blog/‘, include(‘blog.urls‘)),
 8 
 9     url(r^admin/, include(admin.site.urls)),
10 ]

进行单元测试:

1 root@Pad:/home/django/mysite3# python3 manage.py test
2 Creating test database for alias default...
3 .
4 ----------------------------------------------------------------------
5 Ran 1 test in 0.003s
6 
7 OK
8 Destroying test database for alias default...

7行显示,成功。

 

所以,可以看出,此案中,测试函数用于查找“/”目录下的home_page对象,urls.py接受用户请求后,根据正则进行匹配,定向到list应用的views模块的home_page对象

 

reating test database for alias ‘default‘...E======================================================================ERROR: list.tests (unittest.loader.ModuleImportFailure)----------------------------------------------------------------------Traceback (most recent call last):  File "/usr/lib/python3.4/unittest/case.py", line 58, in testPartExecutor    yield  File "/usr/lib/python3.4/unittest/case.py", line 577, in run    testMethod()  File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure    raise exceptionImportError: Failed to import test module: list.testsTraceback (most recent call last):  File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests    module = self._get_module_from_name(name)  File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name    __import__(name)  File "/home/django/mysite3/list/tests.py", line 3, in <module>    from list.views import home_pageImportError: cannot import name ‘home_page‘

----------------------------------------------------------------------Ran 1 test in 0.001s
FAILED (errors=1)Destroying test database for alias ‘default‘...

 

使用TDD理解views.py与urls.py的关系