URL-адреси Django TypeError: перегляд має бути зателефонованим або списком / кортежем у разі включення ()


111

Після оновлення до 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().

Якщо ми використовуємо декоратори на вигляд, і якщо вони нічого не повертають. У цьому випадку ми також отримуємо вище помилки. нещодавно я отримав цю помилку.
anjaneyulubatta505

@AnjaneyuluBatta так, якщо декоратор не поверне подання, то він неявно повертається None, що може спричинити TypeErrorяк вище.
Alasdair

Відповіді:


257

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з декількох додатків без їх зіткнення.

БАЧИТИ URL - адреса Джанго диспетчерських документи для отримання додаткової інформації про urlpatterns.


Що з представленнями на основі класу?
Рішабх Аграхарі

2
Вам ніколи не вдалося використати пунктирний рядок для представлень на основі класів, тому вони не стосуються цього питання.
Alasdair

Я хотів би, щоб зміни, подібні цьому, надходили з деяким помічником (мігруючим сценарієм), оскільки ви також не можете використовувати префікс. import_moduleможе допомогти вам створити власний пошук як обгортку для старовинного рядка, у випадку, коли тисячі URL-адрес чекають на те, щоб оновити їх.
Славомір Ленарт

Ви також повинні імпортувати й інші пакунки - імпортувати з URL-адреси імпорту django.conf.urls. Виправте своє рішення.
WebComer

1
@WebComer Я не включив імпортування URL у запитання / відповідь, оскільки вони залишаються однаковими під час оновлення до Django 1.10 (якщо ви не маєте django.conf.urls.defaultsз Django 1.5 або раніше). Я додав імпорт, як ви запитували, але я не впевнений, що це гарна ідея, оскільки імпорт знову змінюється в Django 2.0. Якщо ви хочете знати правильний імпорт, тоді найкращі місця для пошуку є документи для вашої версії Django (наприклад, 1.11 , 2.0 ).
Alasdair

3

Ця помилка просто означає, що myapp.views.homeце не те, що можна назвати, як функція. Фактично це струна. Незважаючи на те, що ваше рішення працює в django 1.9, воно все ж кидає попередження, кажучи, що це буде застарілим від версії 1.10 і далі, саме це і сталося. Попереднє рішення @Alasdair імпортує необхідні функції перегляду в сценарій через from myapp import views as myapp_views або from myapp.views import home, contact


1

Ви також можете отримати цю помилку, якщо у вас зіткнення імені представлення та модуля. У мене з’явилася помилка, коли я /views/view1.py, /views/view2.pyпоширюю свої файли перегляду під папку «Вид» і імпортував деяку модель під назвою table.py в view2.py, яка, начебто, була назвою представлення у view1.py. Тож іменування функцій перегляду як v_table(request,id) допоможене.


0

Ваш код є

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),
]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.