web-dev-qa-db-fra.com

Django URLs TypeError: view doit être un objet appelable ou une liste/tuple dans le cas de include ()

Après la mise à niveau vers Django 1.10, le message d'erreur suivant s'affiche:

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

Mon urls.py est comme suit:

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

La trace complète est:

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().
87
Alasdair

Django 1.10 ne vous permet plus de spécifier des vues sous forme de chaîne (par exemple 'myapp.views.home') dans vos modèles d'URL.

La solution consiste à mettre à jour votre urls.py pour inclure la vue appelable. Cela signifie que vous devez importer la vue dans votre urls.py. Si vos modèles d'URL ne portent pas de noms, le moment est opportun pour en ajouter un, car l'inversion avec le chemin python en pointillé ne fonctionne plus.

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

S'il existe plusieurs vues, leur importation individuelle peut être gênante. Une alternative consiste à importer le module de vues à partir de votre application. 

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

Notez que nous avons utilisé as myapp_views et as auth_views, ce qui nous permet d'importer le views.py à partir de plusieurs applications sans que celles-ci ne se heurtent.

Voir la documentation Django URL Dispatcher pour plus d'informations sur urlpatterns.

221
Alasdair

Cette erreur signifie simplement que myapp.views.home ne peut pas être appelé, comme une fonction. C'est une ficelle en fait. Bien que votre solution fonctionne dans Django 1.9, elle envoie néanmoins un avertissement indiquant que cela va rendre obsolète la version 1.10, ce qui est exactement ce qui s'est passé. La solution précédente de @Alasdair importe les fonctions de vue nécessaires dans le script par l'intermédiaire de from myapp import views as myapp_views ou from myapp.views import home, contact

3
hAcKnRoCk

Vous pouvez également obtenir cette erreur si vous avez un conflit de noms entre une vue et un module. J'ai l'erreur lorsque je distribue mes fichiers de vue dans le dossier views, /views/view1.py, /views/view2.py et que j'ai importé un modèle nommé table.py dans view2.py, qui s'est avéré être le nom d'une vue dans view1.py. Donc, nommer la vue en tant que v_table(request,id) a aidé.

0
binboavetonik

Votre code est

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

remplacez-le par ceci lorsque vous importez la fonction include():

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