【问题标题】:Django URLs TypeError: view must be a callable or a list/tuple in the case of include()Django URLs TypeError: view must be a callable or a list/tuple in the case of include()
【发布时间】:2023-04-10 00:38:01
【问题描述】:

升级到 Django 1.10 后,出现错误:

TypeError: view must be a callable or a list/tuple in the case of include().

我的urls.py如下:

from django.conf.urls import include, url

urlpatterns = [
    url(r'^$', 'myapp.views.home'),
    url(r'^contact/$', 'myapp.views.contact'),
    url(r'^login/$', 'django.contrib.auth.views.login'),
]

完整的回溯是:

Traceback (most recent call last):
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
    fn(*args, **kwargs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 121, in inner_run
    self.check(display_num_errors=True)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/base.py", line 385, in check
    include_deployment_checks=include_deployment_checks,
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/management/base.py", line 372, in _run_checks
    return checks.run_checks(**kwargs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
    for pattern in resolver.url_patterns:
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/urls/resolvers.py", line 310, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/urls/resolvers.py", line 303, in urlconf_module
    return import_module(self.urlconf_name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/Users/alasdair/dev/urlproject/urlproject/urls.py", line 28, in <module>
    url(r'^$', 'myapp.views.home'),
  File "/Users/alasdair/.virtualenvs/django110/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 85, in url
    raise TypeError('view must be a callable or a list/tuple in the case of include().')
TypeError: view must be a callable or a list/tuple in the case of include().

【问题讨论】:

  • 如果我们在视图上使用装饰器并且它不返回任何东西。在这种情况下,我们也得到了上述错误。最近我收到了这个错误。
  • @AnjaneyuluBatta 是的,如果装饰器不返回视图,那么它会隐式返回 None,这将导致 TypeError 如上所述。

标签: python django django-urls django-1.10


【解决方案1】:

Django 1.10 不再允许您在 URL 模式中将视图指定为字符串(例如 'myapp.views.home')。

解决方案是更新您的urls.py 以包含可调用的视图。这意味着您必须在urls.py 中导入视图。如果您的 URL 模式没有名称,那么现在是添加名称的好时机,因为使用点分 Python 路径进行反转不再有效。

from django.conf.urls import include, url

from django.contrib.auth.views import login
from myapp.views import home, contact

urlpatterns = [
    url(r'^$', home, name='home'),
    url(r'^contact/$', contact, name='contact'),
    url(r'^login/$', login, name='login'),
]

如果有很多视图,那么单独导入它们可能会很不方便。另一种方法是从您的应用程序中导入视图模块。

from django.conf.urls import include, url

from django.contrib.auth import views as auth_views
from myapp import views as myapp_views

urlpatterns = [
    url(r'^$', myapp_views.home, name='home'),
    url(r'^contact/$', myapp_views.contact, name='contact'),
    url(r'^login/$', auth_views.login, name='login'),
]

请注意,我们使用了as myapp_viewsas auth_views,这允许我们从多个应用程序导入views.py 而不会发生冲突。

有关urlpatterns 的更多信息,请参阅Django URL dispatcher docs

【讨论】:

  • 基于类的视图呢?
  • 您永远无法将虚线字符串路径用于基于类的视图,因此它们与此问题无关。
  • 我希望看到这样的更改带有一些帮助程序(迁移脚本),因为您也无法使用前缀。 import_module 可以帮助您构建自己的查找作为旧方式字符串的包装器,以防成千上万的 url 等待您更新它们。
  • 你仍然需要导入其他包 - import from django.conf.urls import url。请修正您的解决方案。
  • @WebComer 我没有在问题/答案中包含 url 导入,因为在升级到 Django 1.10 时它们保持不变(除非您有来自 Django 1.5 或更早版本的 django.conf.urls.defaults)。我已经按照您的要求添加了导入,但我不确定这是一个好主意,因为 Django 2.0 中的导入再次发生了变化。如果您想知道正确的导入,那么您的 Django 版本的文档(例如 1.112.0)是最好的查看位置。
【解决方案2】:

这个错误只是意味着myapp.views.home 不是可以调用的东西,比如函数。它实际上是一个字符串。虽然您的解决方案在 django 1.9 中有效,但它会发出警告说这将从 1.10 版本开始弃用,这正是发生的情况。 @Alasdair 之前的解决方案通过以下任一方式将必要的视图函数导入到脚本中 from myapp import views as myapp_viewsfrom myapp.views import home, contact

【讨论】:

    【解决方案3】:

    如果您有视图和模块的名称冲突,您也可能会收到此错误。当我在视图文件夹/views/view1.py, /views/view2.py 下分发视图文件并在 view2.py 中导入了一些名为 table.py 的模型时,我遇到了错误,这恰好是 view1.py 中视图的名称。因此,将视图函数命名为 v_table(request,id) 会有所帮助。

    【讨论】:

      【解决方案4】:

      你的代码是

      urlpatterns = [
          url(r'^$', 'myapp.views.home'),
          url(r'^contact/$', 'myapp.views.contact'),
          url(r'^login/$', 'django.contrib.auth.views.login'),
      ]
      

      在导入 include() 函数时将其更改为以下:

      urlpatterns = [
          url(r'^$', views.home),
          url(r'^contact/$', views.contact),
          url(r'^login/$', views.login),
      ]
      

      【讨论】:

        【解决方案5】:

        改变 register = template.Library()registerr = template.Library() 解决了我的问题

        【讨论】:

          猜你喜欢
          • 2017-12-03
          • 2021-10-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多