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().
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
.
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
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é.
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),
]