Django URL TypeError:include()の場合、ビューは呼び出し可能またはリスト/タプルでなければなりません


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 2016

@AnjaneyuluBattaはい、デコレータがビューを返さない場合、暗黙的にを返しますNone。これにより、TypeError上記のようになります。
Alasdair 2017年

回答:


257

Django 1.10では'myapp.views.home'、URLパターンで文字列(など)としてビューを指定できなくなりました。

解決策はurls.py、ビューcallableを含めるようにを更新することです。つまり、ビューをにインポートする必要があります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_viewsas auth_views私たちは、インポートすることを可能にする、views.py彼らは衝突することなく、複数のアプリケーションから。

の詳細については、Django URLディスパッチャーのドキュメントを参照してくださいurlpatterns


クラスベースのビューはどうですか?
Rishabh Agrahari 2017年

2
クラスベースのビューにドット付き文字列パスを使用することはできなかったので、この質問には関係ありません。
Alasdair 2017年

プレフィックスも使用できないため、このような変更がヘルパー(移行スクリプト)に付属していることを確認します。import_module何千ものURLが更新を待機している場合に、古い方法の文字列のラッパーとして独自のルックアップを構築するのに役立ちます。
SławomirLenart

他のパッケージもインポートする必要があります-django.conf.urlsからインポートインポートURL。解決策を修正してください。
WebComer 2018年

1
@WebComer Django 1.10にアップグレードするときも同じままであるため、質問/回答にURLインポートを含めませんでした(django.conf.urls.defaultsDjango 1.5以前からの場合を除きます)。要求どおりにインポートを追加しましたが、Django 2.0ではインポートが再び変更されるため、これが良いアイデアかどうかはわかりません。あなたが正しいの輸入を知りたい場合は、ジャンゴ(例えばのバージョンにドキュメント1.112.0)を見に最高の場所です。
Alasdair 2018年

3

このエラーmyapp.views.homeは、関数のように呼び出すことができないことを意味します。実は紐です。あなたのソリューションはdjango 1.9で動作しますが、それでもバージョン1.10以降では非推奨になるという警告がスローされます。これはまさに起こったことです。@Alasdairによる以前の解決策では、必要なビュー関数をスクリプトにインポートするか from myapp import views as myapp_viewsfrom myapp.views import home, contact


1

また、ビューとモジュールの名前の衝突がある場合にも、このエラーが発生することがあります。viewsフォルダーの下にビューファイルを配布し、/views/view1.py, /views/view2.pyたまたまview1.pyのビューの名前であるtable2.pyという名前のモデルをview2.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),
]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.