Подтвердить что ты не робот

Ошибка URL-адресов Django: представление должно быть вызываемым или list/tuple в случае include()

После обновления до Django 1.10 я получаю сообщение об ошибке:

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

My urls.py выглядит следующим образом:

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().
4b9b3361

Ответ 1

Django 1.10 больше не позволяет вам указывать представления в виде строки (например, 'myapp.views.home') в шаблонах URL.

Решение состоит в том, чтобы обновить ваш urls.py, чтобы включить вызываемое представление. Это означает, что вам нужно импортировать представление в urls.py. Если ваши шаблоны URL-адресов не имеют имен, то сейчас самое подходящее время добавить их, потому что обратное с пунктирным путём python больше не работает.

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'),
]

Если существует много просмотров, то их импорт по отдельности может быть неудобным. Альтернативой является импорт модуля views из вашего приложения.

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 из нескольких приложений без их столкновения.

Подробнее о urlpatterns см. Django-диспетчер URL.

Ответ 2

Эта ошибка означает, что myapp.views.home не является тем, что можно назвать, как функция. На самом деле это строка. Хотя ваше решение работает в django 1.9, тем не менее оно выдает предупреждение, в котором говорится, что это будет обесцениваться с версии 1.10, и именно это произошло. Предыдущее решение @Alasdair импортирует необходимые функции просмотра в script через   from myapp import views as myapp_views или   from myapp.views import home, contact