Django URLs TypeError: view debe ser un callable o una lista/tupla en el caso de include()


Después de actualizar a Django 1.10, obtengo el error:

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

Mi urls.py es el siguiente:

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

El rastreo completo es:

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().
Author: Alasdair, 2016-08-03

4 answers

Django 1.10 ya no le permite especificar vistas como una cadena (por ejemplo, 'myapp.views.home') en sus patrones de URL.

La solución es actualizar su urls.py para incluir la vista llamable. Esto significa que tiene que importar la vista en su urls.py. Si sus patrones de URL no tienen nombres, entonces ahora es un buen momento para agregar uno, porque invertir con la ruta de python punteada ya no funciona.

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

Si hay muchas vistas, importarlas individualmente puede ser inconveniente. Una alternativa es importe el módulo views desde su aplicación.

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

Tenga en cuenta que hemos utilizado as myapp_views y as auth_views, lo que nos permite importar el views.py desde múltiples aplicaciones sin que se enfrenten.

Consulte los documentos Django URL dispatcher para obtener más información acerca de urlpatterns.

 208
Author: Alasdair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 08:41:07

Este error solo significa que myapp.views.home no es algo que se pueda llamar, como una función. Es una cadena de hecho. Si bien su solución funciona en django 1.9, sin embargo lanza una advertencia diciendo que esto dejará de funcionar a partir de la versión 1.10 en adelante, que es exactamente lo que ha sucedido. La solución anterior de @Alasdair importa las funciones de vista necesarias en el script a través de cualquiera from myapp import views as myapp_views o from myapp.views import home, contact

 3
Author: hAcKnRoCk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-08 20:16:22

También puede obtener este error si tiene un choque de nombres de una vista y un módulo. Tengo el error cuando distribuyo mis archivos de vista en la carpeta views, /views/view1.py, /views/view2.py e importé un modelo llamado table.py en view2.py que resultó ser el nombre de una vista en view1.py. Así que nombrar las funciones de vista como v_table(request,id) ayudó.

 0
Author: binboavetonik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-06 14:37:03

Su código es

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

Cámbialo a lo siguiente cuando estés importando la función include():

urlpatterns = [
    url(r'^$', views.home),
    url(r'^contact/$', views.contact),
    url(r'^login/$', views.login),
]
 0
Author: Nishant Soni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-25 20:50:20