Django入门练习的两个错误

学习《Python从入门到实践》书中的第18章Django入门时,实践书中代码,遇到'learning_logs' is not a registered namespaceImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.

第一个错误来源

在创建显示Topics数据的网页时,按照书中流程走,创建了父模板,然后子模板继承父模板。
再按照三步标准流程走完:
1 . 添加URL模式;
2 . 视图创建;
3 . 模板创建

一切工作就绪,运行,报错了。
错误如下:

ERROR

添加的父模板,里面有两个链接用到了命名空间learning_logs
父模板代码如下:

<p>
  <a href="{% url 'learning_logs:index' %}">Learning Log</a>
  <a href="{% url 'learning_logs:topics' %}">Topics</a>
</p>
<!-- 插入的块标签 content ,是一个占位符,其中包含的信息将由子模板指定。 -->
{% block content %}{% endblock content %}

排查问题

1 . 首先看项目文件夹下的settings.py文件,确认应用程序learning_logs是否被添加进去了

settings.py

不是这里的问题

2 . 定位到urls.py文件,打开项目文件下的urls.py文件;发现有两个版本的urlpatterns列表.

旧版本,url式的:

from django.conf.urls import url, include

#根据书上的代码写的
urlpatterns = [
    url(r'^admin/',admin.site.urls),
    url(r'',include('learning_logs.urls')),
]

出现新旧版本,原因在于安装的Django的版本,书中的是1.8;而我装的2.1

新版本,path式的:

from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('learning_logs.urls',namespace='learning_logs')),
]

我将path式的注释掉了,用的是url式的。这在今天创建新网页之前,运行都是正常的。

错误解决

首先想到:将url式注释掉,尝试path式,看能否运行正常;结果,又报另一个错误:(

ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.

理解下意思,大致就是:应该在include模块中设置app_name属性,或者传递一个包含模式列表和app_name的2元组
又百度一番,知道了include模块需包含两个参数,前一个为2元组,后一个为namespace;于是将代码修改成这样:

from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include(('learning_logs.urls','learning_logs'),namespace='learning_logs')),    
]

OK! 运行正常

网上搜索一番,发现新旧版本的区别在于是否显示声明namespace的值,在旧版本url式中namespace是注册了的,而新版本未注册。
用url式的代码如下:

from django.conf.urls import url, include

urlpatterns = [
    url(r'^admin/',admin.site.urls),
    url(r'',include(('learning_logs.urls','learning_logs'))),
]

Include只需包含一个参数arg:2元组;namespace不需要显示声明。

到此,问题解决。 完:)

-------------完-------------