Django URLs TypeError: view ต้องเป็น callable หรือ list / tuple ในกรณี 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

@AnjaneyuluBatta ใช่ถ้ามัณฑนากรไม่คืนมุมมองมันก็จะส่งกลับโดยปริยายNoneซึ่งจะทำให้เกิดสิ่งที่TypeErrorกล่าวมาข้างต้น
Alasdair

คำตอบ:


257

Django 1.10 ไม่อนุญาตให้คุณระบุมุมมองเป็นสตริง (เช่น'myapp.views.home') ในรูปแบบ URL ของคุณอีกต่อไป

วิธีแก้ปัญหาคือการอัปเดตของคุณurls.pyเพื่อรวมมุมมองที่เรียกได้ ซึ่งหมายความว่าคุณต้องนำเข้ามุมมองใน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_viewsและas auth_viewsซึ่งช่วยให้เราสามารถนำเข้าviews.pyจากหลาย ๆ แอพโดยไม่ต้องปะทะกัน

ดูDjango URL เอกสารมอบหมายงานurlpatternsสำหรับข้อมูลเพิ่มเติมเกี่ยวกับ


มุมมองตามชั้นเรียนเป็นอย่างไร
Rishabh Agrahari

2
คุณไม่สามารถใช้เส้นทางสตริงที่เป็นจุดสำหรับมุมมองตามคลาสได้ดังนั้นจึงไม่เกี่ยวข้องกับคำถามนี้
Alasdair

ฉันต้องการเห็นการเปลี่ยนแปลงเช่นนี้มาพร้อมกับตัวช่วยบางอย่าง (สคริปต์การย้ายข้อมูล) เนื่องจากคุณไม่สามารถใช้คำนำหน้าได้เช่นกัน import_moduleสามารถช่วยคุณสร้างการค้นหาของตัวเองเป็นกระดาษห่อหุ้มสำหรับสตริงแบบเก่าในกรณีที่มี URL หลายพันรายการรอให้คุณอัปเดต
Sławomir Lenart

คุณยังต้องนำเข้าแพ็กเกจอื่น ๆ ด้วย - นำเข้าจาก django.conf.urls import url โปรดแก้ไขโซลูชันของคุณ
WebComer

1
@WebComer ฉันไม่ได้รวมการนำเข้า url ในคำถาม / คำตอบเพราะยังคงเหมือนเดิมเมื่ออัปเกรดเป็น Django 1.10 (เว้นแต่คุณจะมีdjango.conf.urls.defaultsจาก Django 1.5 หรือก่อนหน้านี้) ฉันได้เพิ่มการนำเข้าตามที่คุณถาม แต่ฉันไม่แน่ใจว่านี่เป็นความคิดที่ดีเนื่องจากการนำเข้ามีการเปลี่ยนแปลงอีกครั้งใน Django 2.0 หากคุณต้องการทราบการนำเข้าที่ถูกต้องเอกสารสำหรับ Django เวอร์ชันของคุณ (เช่น1.11 , 2.0 ) เป็นสถานที่ที่ดีที่สุดในการค้นหา
Alasdair

3

ข้อผิดพลาดนี้หมายความว่าmyapp.views.homeไม่ใช่สิ่งที่สามารถเรียกได้เช่นฟังก์ชัน มันเป็นสตริงในความเป็นจริง แม้ว่าโซลูชันของคุณจะทำงานใน django 1.9 แต่ก็มีคำเตือนว่าสิ่งนี้จะเลิกใช้งานตั้งแต่เวอร์ชัน 1.10 เป็นต้นไปซึ่งเป็นสิ่งที่เกิดขึ้น โซลูชันก่อนหน้านี้โดย @Alasdair นำเข้าฟังก์ชั่นมุมมองที่จำเป็นลงในสคริปต์ผ่านอย่างใดอย่างหนึ่ง from myapp import views as myapp_views หรือ from myapp.views import home, contact


1

คุณอาจได้รับข้อผิดพลาดนี้หากคุณมีชื่อของมุมมองและโมดูล ฉันได้รับข้อผิดพลาดเมื่อฉันแจกจ่ายไฟล์มุมมองของฉันภายใต้โฟลเดอร์มุมมอง/views/view1.py, /views/view2.pyและนำเข้าบางรุ่นชื่อ table.py ใน view2.py ซึ่งเป็นชื่อของมุมมองใน view1.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.