转载自:https://blog.51cto.com/kalson/1975001
分享是快乐的,助人是幸福的。——好吧,装逼到此为止
今天学习django框架跟着网上的教程做网站的时候,碰到一个坑比的现象,本来是跟着网站手敲代码,结果莫名冒出一个 view must be a callable or a list/tuple in the case of include()的TypeError。我很伤心,以为又是自己不细心敲错了,于是直接copy网上的代码,结果还是这样。。。跪了。既然不是我敲打的问题,那一定是语法的问题了。然后就网上查找原因,最后找到这篇文章
http://blog.csdn.net/gavinking0110/article/details/53738362
给我带来启发(版本问题,写法不一致)。下面直接看代码讲解了。
from django.conf.urls import url,include
from django.conf import settings
from django.contrib import admin
from DjangoUeditor import urls as DjangoUeditor_urls
from news import views as new_views
urlpatterns = [
# url(r'^$','news.views.index',name='index'),
# url(r'^column/(?p<column_slug>[^/]+)/$','new_views.column_detail',name='column'),
# url(r'^news/(?p<article_slug>[^/]+)/$','new_views.article_detail',name='article'),
url(r'^$', new_views.index, name='index'),
url(r'^column/(?P<column_slug>[^/]+)/$', new_views.column_detail, name='column'),
url(r'^news/(?P<article_slug>[^/]+)/$', new_views.article_detail, name='article'),
url(r'^admin/',admin.site.urls),
url(r'ueditor/',include(DjangoUeditor_urls)),
]
注释掉的部分是我自己根据网站写的内容,下面部分是我修改后的内容。根据上篇博文的介绍,应该就是Django框架版本升级的原因了。
url的源码如下
def url(regex, view, kwargs=None, name=None):
if isinstance(view, (list, tuple)):
# For include(...) processing.
urlconf_module, app_name, namespace = view
return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace)
elif callable(view):
return RegexURLPattern(regex, view, kwargs, name)
else:
raise TypeError('view must be a callable or a list/tuple in the case of include().')
根据源码可知,针对view这个参数,它并没有做任何格式的处理,因此我们写的
'new_views.column_detail'
就是一个字符串,显然字符串并不是list也不是tuple(这个很好验证)。
abc='abc'
if isinstance(abc, (list, tuple)):
print 'True'
else:
print 'False'
结果:False
也许你会想,后面还有callable这个可以执行呢,我们看源码:
def callable(p_object): # real signature unknown; restored from __doc__
"""
callable(object) -> bool
Return whether the object is callable (i.e., some kind of function).
Note that classes are callable, as are instances with a __call__() method.
"""
return False
哈哈哈,很不幸,你的想法又错了,源码显示,不管你输入什么,这里都是执行return False。所以在这里,elseif那句就是废话。
那这样就只能证明
new_views.article_detail
正确写法是一个list或者tuple了(这个我验证过后再写验证方法)。——更新:request.GET 类似于一个字典,更好的办法是用 request.GET.get('a', 0) 当没有传递 a 的时候默认 a 为 0。这个是网上教程提供出来的,所以目前是可以理解了。针对这种带有前端视图的,目前我的知识还不知道如何去验证。
温馨提示:再使用django的时候,再开启server后,默认我们修改内容后会自动刷新,奇怪的是针对这个问题,修改后需要我们停止重新再启动才可以。默认出现这个错误之后即使修改正确了也不会刷新(这个有点坑爹啊,我还一直ctrl+s等他刷新呢)。
我的django版本如下:
django.VERSION
(1, 11, 6, u'final', 0)