Na het upgraden naar Django 1.10 krijg ik de foutmelding:
TypeError: view must be a callable or a list/tuple in the case of include().
Mijn urls.py is als volgt:
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'),
]
De volledige traceback is:
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().
Antwoord 1, autoriteit 100%
Django 1.10 staat je niet langer toe om views op te geven als een string (bijv. 'myapp.views.home'
) in je URL-patronen.
De oplossing is om uw urls.py
bij te werken om de aanroepbare weergave op te nemen. Dit betekent dat u de weergave moet importeren in uw urls.py
. Als uw URL-patronen geen namen hebben, is het nu een goed moment om er een toe te voegen, omdat omkeren met het gestippelde python-pad niet meer werkt.
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'),
]
Als er veel weergaven zijn, kan het lastig zijn om ze afzonderlijk te importeren. Een alternatief is om de views-module uit uw app te importeren.
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'),
]
Merk op dat we as myapp_views
en as auth_views
hebben gebruikt, waardoor we de views.py
uit meerdere apps kunnen importeren zonder dat ze botsen .
Zie de Django URL-dispatcher docsvoor meer informatie over urlpatterns
.
Antwoord 2
Deze fout betekent alleen dat myapp.views.home
niet iets is dat kan worden aangeroepen, zoals een functie. Het is in feite een string. Hoewel uw oplossing werkt in django 1.9, geeft het toch een waarschuwing dat dit vanaf versie 1.10 zal worden beëindigd, en dat is precies wat er is gebeurd. De vorige oplossing van @Alasdair importeert de benodigde weergavefuncties in het script via een van beide
from myapp import views as myapp_views
of
from myapp.views import home, contact
Antwoord 3
Je kunt deze fout ook krijgen als je een naamclash hebt van een weergave en een module. Ik heb de fout wanneer ik mijn weergavebestanden distribueer in de map views, /views/view1.py, /views/view2.py
en een model met de naam table.py in view2.py importeerde wat gebeurde om een naam te zijn van een weergave in view1.py. Dus het benoemen van de weergavefuncties als v_table(request,id)
hielp.
Antwoord 4
Uw code is
urlpatterns = [
url(r'^$', 'myapp.views.home'),
url(r'^contact/$', 'myapp.views.contact'),
url(r'^login/$', 'django.contrib.auth.views.login'),
]
wijzig het in het volgende terwijl u de functie include()
importeert:
urlpatterns = [
url(r'^$', views.home),
url(r'^contact/$', views.contact),
url(r'^login/$', views.login),
]
Antwoord 5
wijzigen
register = template.Library()
naar
registerr = template.Library()
mijn probleem opgelost