最近学习了Python编程:从入门到实践的第三个项目,Web应用程序。书上项目实现时,遇到了许多问题,问题的主要原因基本都是由于Django已经更新到2.1.4版本了,书中的代码还是采用的1.8.5版本。
为了帮助后面的新同学快速避坑,迅速解决书中代码无法实现的问题,现将学习中遇到的问题进行汇总,欢迎留言补充……

本人系统环境:
WIN10系统家庭版
Python 3.7.1
Django 2.1.4

书本环境:
Python 3.x
Django 1.8.5

1) 解决版本问题的初级方法

如果你想按照书中的代码实现项目,可以执行在CMD窗口执行卸载命令卸载Django,然后安装书中的用到的版本,命令如下:
卸载命令:pip uninstall Django
安装命令:pip install Django=1.8.5

补充问题1:有些同学采用pip命令时候可能会提示pip版本过低,先将pip升级:
升级命令:python -m pip install -U pip
或者 python -m pip install --upgrade pip

补充问题2:由于网络问题采用pip命令安装失败,可以在官网或者阿里云下载whl源文件到本地,然后安装

建议大家还是采用最新的版本,通过修改代码实现文中的项目,先将问题按章节进行列出

**

2) 第18章 18.1.3 创建虚拟工作环境

**
书中是写的在终端中切换到目录learning_log,并像下面这样创建一个虚拟环境:
virtualenv ll_env
运行后出现错误,代码应改写为:
python -m venv 11_env
然后项目文件夹下就创建了虚拟环境所在的文件夹11_env

**

3) 第18章 18.1.6 在Django中创建项目

**
有的同学提到由于Django采用PIP安装的,创建项目采用以下命令会出现错误:
django-admin.py startproject learning_log .
我的Django也是pip安装的,但是采用上面和下面的代码都可以正确的创建项目:
django-admin startproject learning_log .

**

4) 第18章 18.2.4 在Django 定义模型Entry

**
定义模型里面有定义一个外键,书中代码为:
topic = models.ForeignKey(Topic)
运行会提示缺少on_delete参数,因为在django2.0后,定义外键和一对一关系的时候需要加on_delete选项,此参数为了避免两个表里的数据不一致问题,不然会报错,例如user=models.OneToOneField(User,on_delete=models.CASCADE),因此,代码修改为:
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)

关于on_delete参数的说明:
参数说明:
on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值
CASCADE:此值设置,是级联删除。
PROTECT:此值设置,是会报完整性错误。
SET_NULL:此值设置,会把外键设置为null,前提是允许为null。
SET_DEFAULT:此值设置,会把设置为外键的默认值。
SET():此值设置,会调用外面的值,可以是一个函数。
一般情况下使用CASCADE就可以了。具体可以参考官方文档:
https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.ForeignKey

**

5)第18章 18.2.6 向管理网站注册Entry

**
运行书中步骤后,返回网站,并没有看到Entries,只需要关闭虚拟环境,关闭浏览器,重新打开CMD,激活虚拟环境,运行python manage.py runserver,然后打开浏览器。

**

6) 第18章 18.3.1 映射URL

**
文中源代码为:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r’^admin/’, include(admin.site.urls)),
url(r’’, include(‘learning_logs.urls’, namespace=‘learning_logs’)),
]
如果采用文中源代码,运行python manage.py runserver查看项目,会出现错误,错误提示中会出现类似namespace的错误,没有app_name等的错误,需要在代码开始前添加app_name的定义。
由于Django2.0之后版本已经修改代码格式,这里需要修改为以下代码:
from django.contrib import admin
from django.urls import path, include

app_name=‘learning_logs’

urlpatterns = [
path(‘admin/’, admin.site.urls),
path(’’, include(‘learning_logs.urls’, namespace=‘learning_logs’)),
]
然后就可以正常运行了,现在打开http://localhost:8000/,就能查看到网页了。

**

7) 第18章 18.4.3 显示特定主题的页面

**
坑1:注意topics和topic的区别,要新建一个topic.html文件
坑2:views需要新建一个topic的方法,小心代码中的topic别写错为topics了

我的代码全部修改后,打开网页topics,然后点击单个主题chess后出现了以下错误:

网页错误代码如下:
‘function’ object has no attribute ‘entry_set’
Request Method: GET
Request URL: http://localhost:8000/topics/(%3FP1%5Cd+)/
Django Version: 2.1.4
Exception Type: AttributeError
Exception Value: ‘function’ object has no attribute ‘entry_set’
Exception Location: D:\Python_env\learning_log\learning_logs\views.py in topic, line 20

源代码为:

from django.shortcuts import render
from .models import Topic

# Create your views here.

def index(request):
    return render(request, 'learning_logs/index.html')
    

def topics(request):
    """显示所有的主题"""
    topics = Topic.objects.order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)
    

def topic(request, topic_id):
	"""显示单个主题及其所有的条目"""
	topic = Topic.objects.get(id = topic_id)
	entries = topic.entry_set.order_by('-date_added')
	context = {'topic': topic, 'entries': entries}
	return render(request, 'learning_logs/topic.html', context)

仔细检查了发现格式书写都没有问题,缩进也没有看出来有问题,然后我将entry_set.order_by删除了,又重新书写了一遍,然后,保存,刷新了一下网页,然后点击chess可以正常跳转打开。
该问题未找到原因所在,以前有时候代码也莫名其妙运行不了,但是鼓捣几下就好了,用的的Geany编辑器,不知道有同学遇到过类似问题没有,我知道肯定是哪里出了问题,问题原因还么有找到,代码就又运行成功了。。。。。。无解

未完待续。。。 欢迎回复补充。。。