书籍名称:[Python3 自动化软件发布系统-Django2 实战]
函数视图操作 ORM(显示 board 列表)
编写 boards_list 视图
在bbs/views.py 里新增一个 boards_list 函数
1 | from .models import Board |
代码解释:
使用 objects 管理器的 all() 方法,获取 Board 表中的所有记录,这条 ORM 略相当于 [SELECT id, name, description FROM Board;], 然后使用 render 这个快捷方法,渲染 boards_list.html 模板,传递一个 boards 上下文;
编写 boards_list 模板
在 bbs/templates/bbs/ 目录下新增一个模板文件 boards_list.html,内容如下:
1 |
|
代码解释:
- 这里以最简单的方式实现了一个显示所有 board 名称及描述的列表。
- 第9~13行:实现了循环读取每一条 board 的功能。
- 第10行:显示指定的 board 的 URL,在下一小节实现;注意,我们为这个 URL 指定了一个参数: board.pk,这个参数是需要名为 board_topics 的 URL 来捕获的;
- 第11~12行:{{ board.id }} 这样的模板变量,用于显示 board 的 id, 名称及描述;
添加 boards_list 路由
在 django_demo_project/urls.py 里面,新增一条 URL 路由
1 | urlpatterns = [ |
测试 boards_list 访问
启动服务,在浏览器访问 http://127.0.0.1:8000/boards_list/
,此时访问报如下错误,因为 board_topics 视图并没有写完;
1 | reverse for 'board_topics' with arguments '(1,)' not found. 1 pattern(s) tried: ['board_topics/$'] |
函数视图操作 ORM(显示指定 board 的 topic 列表)
编写 board_topics 视图
在 bbs/views.py 文件里新增 board_topics 函数
1 | def board_topics(request, pk): |
代码解释:
- 第1行,由于我们在此函数的 URL 中捕获了一个 pk 参数,所以将其传送到了函数;
- 第2行,使用 objects 管理器的 all() 方法,获取指定的 board 实例;
- 第3行,使用 Topic 数据表中 board 外键的 related_name(topics),获取了指定 board 的所有 topic;
- 第4行,使用 render 方法渲染 board_topics.html 模板,传递一个 board 和 topics 上下文;
编写 board_topics 模板
在 bbs/templates/bbs/ 目录下,新增一个上文提到的模板文件 board_topics.html
1 | <div class="table table-striped mb-4"> |
代码解释:
- 第2行,发帖功能,在接下来实现;
- 第15~26行,实现了循环读取每一条 topic 的功能;
- 第19行,显示指定了 topic 内容的 URL,并为这个 URL 传递了两个参数:board.pk,topic.pk;
- 第22行,{{ topic.starter.username }} 这样的模板变量,用于显示 topic 中的 starter 这个外键数据表中的 username 字段名称;
添加 board_topics 路由
在 django_demo_project/urls.py 文件中新增一条路由实例
1 | urlpatterns = [ |
测试 board_topics 访问
启动服务,在浏览器访问 http://127.0.0.1:8000/boards_list/
,然后点击 Python 链接。此时访问报如下错误,因为缺少 new_topic 视图;
1 | Reverse for 'new_topic' not found. 'new_topic' is not a valid view function or pattern name. |
函数视图操作 ORM(新增 topic)
新增 Form 文件
在 bbs/ 目录下,新增一个 forms.py 文件
1 | from django import forms |
代码解释:
- 我们这里实现了一个 Django 的 ModelForm。关于表单的知识会在后面讲述,这里可以理解为网页里的一个
<form></form>
之间的内容;
编写 new_topic 视图
在 bbs/views.py 文件里新增一个 new_topic 函数
1 | def new_topic(request, pk): |
代码解释:
- 由于在此函数的 URL 中捕获了一个 pk 参数,所以将其传递到了函数;
- get_object_or_404 这个方法,相当于使用 objects 管理器的 get 方法,但是同时判断了出错的情况,如果有数据,则与 get 方法一样返回;如果没有数据,则直接给网页返回 404 错误;
- 第4~18行,如果在网页中以 POST 方法提交数据,,则这里的逻辑上会保存这个 topic 数据,之后,URL 会跳转到这个新的 topic,因为用户有新增 topic 时,subject 是属于 Topic 表,而message 是属于 Post 表,所以这里做了分开保存;form.is_valid() 这样的方法后面讲到 Django 表单的时候再分析;
- 第20行,如果在网页中以 GET 方法请求此 URL,则调用 render 方法,并指定一个新的 form;
编写 new_topic 模板
在 bbs/templates/bbs/ 目录下,新增上文提到的模板文件 new_topic.html
1 | <li><a href="{% url 'boards_list' %}"> Borads</a></li> |
代码解释:
- 第1~2行,如果用户不准备发新帖了,则提供一个返回前两级网页的 URL 链接;
- 第5~45行,实现了一个 form 表单,我们逐条渲染 form 表单里的每个字段,并且将是否有错误提示也一并渲染;
- 第6行,{% csrf_token %} 这里是为了增加表单的安全性而设计的 token;
添加 new_topic 路由
在 django_demo_project/urls.py 文件添加一条路由实例
1 | urlpatterns = [ |
测试 new_topic 访问
浏览器输入 http://127.0.0.1:8000/boards/2/new/
,测试访问是否正常;
函数视图操作 ORM(指定 board 的 topic 内容)
编写 topic_posts 视图
在 bbs/views.py 中新增一个 topic_posts 函数
1 | def topic_posts(request, pk, topic_pk): |
代码解释:
- 第1行,由于此函数的 URL 中捕获了两个参数,一个是 board 的 pk,一个是 topic 的 pk,所以将其传递到了函数;
- 第2行,使用 objects 管理器的 get() 方法,获取指定的 topic 实例;
- 第3行,使用 Post 数据表中 topic 外键的 related_name(posts),获取了指定 topic 的所有 post;
- 第4~6行,使用 render 方法,渲染 posts.html 模板,并传递了上下文。
编写 topic_posts 模板
在 bbs/templates/bbs/ 目录下,新增一个上文提到的模板文件 posts.html
1 | <div> |
代码解释:
- 第2行,建立一个 URL 连接,可以回到此 board;
- 第6~27行,实现了循环读取 topic 的第一个 post 的内容;
- 第13行, 这样的模板变量,用于显示 topic 中的 created_by 这个外键数据表中的 username 字段名称;
添加 topic_posts 路由
在 django_demo_project/urls.py 文件中新增一条 URL 实例
1 | urlpatterns = [ |
测试 topic_posts 访问
在浏览器中点击帖子列表,查看效果;
类视图操作 ORM(显示 board 列表)
前面演示的都是用函数视图来操作的 ORM,Python 是一个面向对象的编程语言,如果只用函数来开发,那么有很多面向对象的优点就错失了。所以 Django 在后来加入了 Class-Based-View,可以让我们用类写 View。这样做的优点是不但提高了代码的复用性,可以使用面向对象的技术,比如 Mixin(多继承),而且可以用不同的函数针对不同的 HTTP 方法处理,而不是通过很多的 if 判断,提高了代码的可读性。
下面就来实现一个简单的类视图:
编写 BoardList 类视图
在 bbs/views.py 里面新增一个 BoardList 类
1 | class BoardList(ListView): |
代码解释:
- 第1行,BoardList 类继承了一个通用的 ListView 类。更多的通用类稍后说明;
- 第2行,此类视图使用的 Model 为 Board;
- 第3行,重定义类视图的上下文变量名为 boards,不然默认的为 object_list;
- 第4行,定义此类视图使用的模板同样为 bords_list.html。为了和函数视图保持兼容,这里定义的上下文和模板名称与函数视图中的一模一样。
新建 boards_list 模板
这里不用新建模板文件,就使用 bbs/templates/bbs/boards_list.html 作为模板
添加路由实例
在 django_demo_project/urls.py 文件中添加路由实例
1 | urlpatterns = [ |
测试访问
在浏览器里面访问 http://127.0.0.1:8000/boards_list_view/
, 查看效果
Django 中的类视图
类别 | 名称 |
---|---|
基本类别 | TemplateView |
RedirectView | |
通用显示视图 | DetailView |
ListView | |
通用编辑视图 | FormView |
CreateView | |
UpdateView | |
DeleteView | |
通用日期视图 | ArchiveIndexView |
YearArchiveView | |
MonthArchiveView | |
WeekArchiveView | |
DayArchiveView | |
TodayArchiveView | |
DateDetailArchiveView |
设置 Django 使用 MySQL
如果要将 Django 后端连接的数据库配置为 MySQL,则只需要将 settings.py 中的 DATABASES 配置修改为如下内容即可:
1 | DATABASES = { |
注意几点:
- 需要提前在 MySQL 中建好数据库;
- 需要使用 pip 安装类似 pymysql 的模块;
- 以上是最低配置,在生产环境需要更详细的配置,请参考更多文档。