Django URL TypeError: view phải là một danh sách có thể gọi hoặc một danh sách / tuple trong trường hợp bao gồm ()


111

Sau khi nâng cấp lên Django 1.10, tôi gặp lỗi:

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

Urls.py của tôi như sau:

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

Theo dõi đầy đủ là:

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

Nếu chúng tôi sử dụng trình trang trí trên chế độ xem và nếu nó không trả lại bất cứ điều gì. Trong trường hợp này, chúng tôi cũng nhận được lỗi ở trên. gần đây tôi gặp lỗi này.
anjaneyulubatta505

@AnjaneyuluBatta vâng, nếu một người trang trí không trả về một chế độ xem thì nó sẽ trả về một cách ngầm định None, điều này sẽ gây ra TypeErrornhư trên.
Alasdair

Câu trả lời:


257

Django 1.10 không còn cho phép bạn chỉ định chế độ xem dưới dạng một chuỗi (ví dụ 'myapp.views.home') trong các mẫu URL của bạn.

Giải pháp là cập nhật của bạn urls.pyđể bao gồm chế độ xem có thể gọi được. Điều này có nghĩa là bạn phải nhập chế độ xem trong của bạn urls.py. Nếu các mẫu URL của bạn không có tên, thì bây giờ là thời điểm tốt để thêm một tên, vì việc đảo ngược với đường dẫn python chấm chấm không còn hoạt động nữa.

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

Nếu có nhiều chế độ xem, việc nhập chúng riêng lẻ có thể bất tiện. Một giải pháp thay thế là nhập mô-đun chế độ xem từ ứng dụng của bạn.

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

Lưu ý rằng chúng tôi đã sử dụng as myapp_viewsas auth_viewscho phép chúng tôi nhập views.pytừ nhiều ứng dụng mà chúng không bị đụng độ.

Xem tài liệu của trình điều phối URL Django để biết thêm thông tin về urlpatterns.


Còn về chế độ xem dựa trên lớp thì sao?
Rishabh Agrahari

2
Bạn chưa bao giờ có thể sử dụng đường dẫn chuỗi chấm cho các dạng xem dựa trên lớp, vì vậy chúng không liên quan đến câu hỏi này.
Alasdair

Tôi muốn thấy sự thay đổi như thế này đi kèm với một số trợ giúp (một tập lệnh di chuyển), bởi vì bạn cũng không thể sử dụng tiền tố. import_modulecó thể giúp bạn xây dựng tra cứu của riêng mình dưới dạng trình bao bọc cho chuỗi theo cách cũ, trong trường hợp hàng nghìn url đang chờ bạn cập nhật chúng.
Sławomir Lenart

Bạn vẫn phải nhập các gói khác - nhập từ url nhập django.conf.urls. Hãy sửa giải pháp của bạn.
WebComer

1
@WebComer Tôi đã không bao gồm nhập url trong câu hỏi / câu trả lời vì chúng vẫn giữ nguyên khi nâng cấp lên Django 1.10 (trừ khi bạn có django.conf.urls.defaultstừ Django 1.5 trở xuống). Tôi đã thêm các mục nhập như bạn đã hỏi, nhưng tôi không chắc rằng đây là một ý tưởng hay, vì các mục nhập lại thay đổi trong Django 2.0. Nếu bạn muốn biết các lần nhập chính xác, thì các tài liệu cho phiên bản Django của bạn (ví dụ: 1.11 , 2.0 ) là nơi tốt nhất để xem.
Alasdair

3

Lỗi này chỉ có nghĩa là đó myapp.views.homekhông phải là một cái gì đó có thể được gọi, như một hàm. Nó là một chuỗi trên thực tế. Mặc dù giải pháp của bạn hoạt động trong django 1.9, tuy nhiên, nó đưa ra một cảnh báo nói rằng tính năng này sẽ không được chấp nhận từ phiên bản 1.10 trở đi, đó chính xác là những gì đã xảy ra. Giải pháp trước đây của @Alasdair nhập các chức năng xem cần thiết vào tập lệnh thông qua from myapp import views as myapp_views hoặc from myapp.views import home, contact


1

Bạn cũng có thể gặp lỗi này nếu bạn có xung đột tên của một chế độ xem và một mô-đun. Tôi đã gặp lỗi khi phân phối tệp dạng xem của mình trong thư mục dạng xem /views/view1.py, /views/view2.pyvà nhập một số mô hình có tên table.py trong view2.py mà tình cờ là tên của dạng xem trong view1.py. Vì vậy, đặt tên cho các chức năng xem như v_table(request,id) đã giúp.


0

Mã của bạn là

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

thay đổi nó thành sau khi bạn đang nhập include()hàm:

urlpatterns = [
    url(r'^$', views.home),
    url(r'^contact/$', views.contact),
    url(r'^login/$', views.login),
]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.