问题:Django URLs TypeError:对于include(),视图必须是可调用的或列表/元组
升级到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().
After upgrading to Django 1.10, I get the error:
TypeError: view must be a callable or a list/tuple in the case of include().
My urls.py is as follows:
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'),
]
The full traceback is:
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().
回答 0
Django 1.10不再允许您'myapp.views.home'
在URL模式中将视图指定为字符串(例如)。
解决方案是更新您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_views
和as auth_views
,这允许我们views.py
从多个应用程序导入,而不会发生冲突。
有关的更多信息,请参见Django URL调度程序文档urlpatterns
。
Django 1.10 no longer allows you to specify views as a string (e.g. 'myapp.views.home'
) in your URL patterns.
The solution is to update your urls.py
to include the view callable. This means that you have to import the view in your urls.py
. If your URL patterns don’t have names, then now is a good time to add one, because reversing with the dotted python path no longer works.
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'),
]
If there are many views, then importing them individually can be inconvenient. An alternative is to import the views module from your app.
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'),
]
Note that we have used as myapp_views
and as auth_views
, which allows us to import the views.py
from multiple apps without them clashing.
See the Django URL dispatcher docs for more information about urlpatterns
.
回答 1
该错误仅意味着myapp.views.home
不能调用它,就像函数一样。它实际上是一个字符串。当您的解决方案在django 1.9中运行时,它仍然发出警告,说它将从版本1.10开始弃用,这就是发生的一切。通过@Alasdair先前的溶液中导入必要的视图函数到脚本通过任一
from myapp import views as myapp_views
或
from myapp.views import home, contact
This error just means that myapp.views.home
is not something that can be called, like a function. It is a string in fact. While your solution works in django 1.9, nevertheless it throws a warning saying this will deprecate from version 1.10 onwards, which is exactly what has happened. The previous solution by @Alasdair imports the necessary view functions into the script through either
from myapp import views as myapp_views
or
from myapp.views import home, contact
回答 2
如果视图和模块的名称冲突,也可能会出现此错误。我将我的视图文件分发到views文件夹下,/views/view1.py, /views/view2.py
并在view2.py中导入了一个名为table.py的模型时遇到了错误,该模型恰巧是view1.py中的视图名称。因此,命名视图功能 v_table(request,id)
很有帮助。
You may also get this error if you have a name clash of a view and a module. I’ve got the error when i distribute my view files under views folder, /views/view1.py, /views/view2.py
and imported some model named table.py in view2.py which happened to be a name of a view in view1.py. So naming the view functions as v_table(request,id)
helped.
回答 3
您的代码是
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),
]
Your code is
urlpatterns = [
url(r'^$', 'myapp.views.home'),
url(r'^contact/$', 'myapp.views.contact'),
url(r'^login/$', 'django.contrib.auth.views.login'),
]
change it to following as you’re importing include()
function :
urlpatterns = [
url(r'^$', views.home),
url(r'^contact/$', views.contact),
url(r'^login/$', views.login),
]