"Include" 工作异常

"Include" works weirdly

我最近开始为 python 开发 Django 1.9。我也是 python 的新手。只是通过示例和代码来学习东西。 我在 django.conf.urls 中遇到了 include ,当我使用它时导致了错误。我不明白这是为什么?因为我在别的地方用过,不会出错。

from django.conf.urls import url, include
from accounts import views as acc_views
urlpatterns = [
    url(r'^home$', acc_views.home, name='accounts_home'),
]

下面是出现错误的时候。

urlpatterns = [
    url(r'^home$', include(acc_views.home), name='accounts_home'),
]

这里是例外:

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x035424F8>
Traceback (most recent call last):
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\urlresolvers.py", line 419, in url_patterns
    iter(patterns)
TypeError: 'function' object is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\utils\autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\management\commands\runserver.py", line 116, in inner_run
    self.check(display_num_errors=True)
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\management\base.py", line 426, in check
    include_deployment_checks=include_deployment_checks,
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\checks\registry.py", line 75, in run_checks
    new_errors = check(app_configs=app_configs)
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\checks\urls.py", line 27, in check_resolver
    warnings.extend(check_resolver(pattern))
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\checks\urls.py", line 27, in check_resolver
    warnings.extend(check_resolver(pattern))
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
    for pattern in resolver.url_patterns:
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\utils\functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\urlresolvers.py", line 426, in url_patterns
    raise ImproperlyConfigured(msg.format(name=self.urlconf_name))
django.core.exceptions.ImproperlyConfigured: The included URLconf '<function home at 0x03D45A50>' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.

include 到底在做什么?

您似乎包含 view 而不是 urls 模块

url(r'^home$', include(acc_views.home), name='accounts_home'),

应该是

 url(r'^account/', include(account.urls, namespace='accounts'),

Include 旨在让 link 不同 urls.py 文件之间的模式变得容易,而不是包含单独的视图,为此您可以直接在 url 和平时一样。

What is include actually doing?

您可以查看source code here

它本质上是寻找在 urlpatterns 变量中定义的模式。

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x035424F8>
Traceback (most recent call last):
  File "C:\Python35-32\VirtualENV\socialnetwork296\lib\site-packages\django\core\urlresolvers.py", line 419, in url_patterns
    iter(patterns)
TypeError: 'function' object is not iterable

这告诉了您应该知道的一切。函数不可迭代。如果你 read the docs 你会发现你可以使用以下任何一个:

include(module, namespace=None, app_name=None)[source]
include(pattern_list)
include((pattern_list, app_namespace), namespace=None)
include((pattern_list, app_namespace, instance_namespace))

我猜你是在给它传递一个函数,acc_views.home。您可能想要 'acc_views.home' 字符串 或类似的东西,而不是实际的模块。

include 通过包含其他 django 模块的 urls 并使用当前定义作为其他模块下面的根来工作。

Django doc对此有很全面的解释,我在这里引用一下:

from django.conf.urls import include, url

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    url(r'^reports/$', credit_views.report),
    url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
    url(r'^charge/$', credit_views.charge),
]

urlpatterns = [
    url(r'^$', main_views.homepage),
    url(r'^help/', include('apps.help.urls')),
    url(r'^credit/', include(extra_patterns)),
]

此处 include(extra_patterns) 将使用 credit/ 作为根 url 并将 extra_patterns 中定义的任何其他 url 识别为 url 定义来匹配 urls。这避免了重复定义,如 credit/reportscredit/charge

include('apps.help.urls') 相同,它将包括模块 apps.help.urls 中定义的所有 url,基数 url 为 help/。因此,您不必在一处定义所有 url。