分享是快乐的,助人是幸福的。——好吧,装逼到此为止

今天学习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)

对你有用就给个赞吧,鼓励我继续装逼。