你的Bookstore
参考资料
一、Django 核心概念与原理
1.1 项目结构与文件说明
创建一个 Django 项目:
|
|
项目目录下各核心文件的作用:
manage.py:管理 Django 项目的命令行工具,主要用于启动项目、创建应用和完成数据库的迁移等__init__.py:用于标识当前所在目录是一个 Python 包。如果在此文件中通过 import 导入其他方法或者包,会被 Django 自动识别settings.py:Django 项目的重要配置文件。项目启动时会被自动调用,定义的全局参数为 Django 运行提供参数,也可以在此自定义变量,用于全局作用域的数据传递。注意:添加应用后需要在INSTALLED_APPS中注册urls.py:用于记录 Django 项目的 URL 映射关系,属于项目的基础路由配置文件。项目中的动态路径必须先经过该文件匹配,才能实现 Web 站点上资源的访问功能wsgi.py:WSGI(Web Server Gateway Interface)服务器程序的入口文件,主要用于启动应用程序。它遵守 WSGI 协议并负责网络通讯部分的实现,只有在项目部署的时候才会用到
启动项目:
|
|
如果是在局域网内,想让其他电脑访问你的 Django 项目:
|
|
1.2 URL 路由系统
URL 基础
统一资源定位符(URL),用来表示互联网上的某个资源地址。互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
语法格式:
|
|
分别对应:协议、主机名、端口号、路由、查询、信息片段。有些特殊的符号无法直接在 URL 中使用,需要用该符号对应的 ASCII 编码值。
反向解析
动态解析 URL 的方法,用于避免"当路由匹配关系发生变化,与之对应的访问地址也需要跟着改变"的情况。使用 Path 语法提供的 name 属性给对应路由起别名,根据这个别名来动态解析 URL。
命名空间(namespace)
即使在不同的应用(app)中定义了相同的 URL 名称,也能够正确实现 URL 反向解析。
应用级路由(include)
一个 Django 项目会包含很多的 app,只在主路由里进行配置就会显得杂乱无章。通常会在每个 app 里创建各自的 urls.py 路由模块,然后从根路由出发,将 app 所属的 URL 请求全部转发到相应的 urls.py 模块中:
|
|
1.3 视图层
模板系统与视图解耦
前端页面需要经常改动,比如电商网站到了双十一搞活动的时候。如果将页面放到视图函数中,那么当对前端页面修改的时候,也会使得视图函数发生变化,故通过模板(Template)系统实现视图函数与 HTML 代码解耦。
- 视图层编写代码
- 编写 HTML 页面
在项目的同级目录下创建名为 templates 的文件夹,对它进行简单的配置后,这个文件夹将被 Django 自动识别。
模板传参:视图函数必须把数据形成字典的形式才可以传递给模板。
render 方法:首先加载模板,然后将加载完成的模板响应给浏览器。
FBV 与 CBV
FBV(Function Based Views)基于函数的视图;CBV(Class Based Views)基于类的视图。
|
|
1.4 模板系统
常见模板标签
if标签for标签——与 Python 中的 for 循环不同的是,只能一次性地遍历完列表中的元素,不能中断(break),也不能跳过(continue)
|
|
url标签{% load static %}加载静态文件{% ifchanged %}检查值是否已更改comment标签,用来快速实现多行注释
条件判断示例:
|
|
注意:双重括号之间不要空格;模板标签内部的两边空格不要省略。
模板继承
可以构建基本的"骨架"模板,将通用的功能或者属性写在基础模板中,子模板可以继承父类模板,大大提高了代码的可重用性,减轻开发人员的工作量。常用标签:{% block %} 与 {% extends %} 标签。
1.5 模型与 ORM
ORM 概述
Model 中添加的字段都是 Field 类型的实例。Field 类型中有通用字段选项。ORM 模块提供了丰富的 API 用于实现对 Model 的增删改查。但是对于 Web 站点的管理运营人员来说,学习它们的成本较高,且误操作的可能性较大,故需要超级用户。
数据表迁移
|
|
“迁移"就是把 Django 默认自带应用的数据表迁移到我们自己创建的数据库里,有点像搬家的意思。
Admin 后台与超级用户
将 Model 注册到管理后台:把 Model 显示在 Admin 后台管理系统界面,需要在 admin.py 文件中进行声明。
创建超级用户:
|
|
超级用户拥有所有权限,方便以可视化的形式对应用数据记录实现增删改查的操作。
1.6 表单系统
实现一个 Web 站点的注册、登出、退出以及用户登录时的校验,可以利用 HTML 中的 form 表单通过 POST 传参到服务器,也可以使用 Django 的表单系统。
使用 Django 表单系统的好处:
- 自动生成 HTML 表单元素
- 对用户提交的数据进行校验
- 对校验存在错误的数据进行回显,告知错误
- 将表单数据转换为对应的 Python 数据类型
表单字段基类 Field 的方法:
clean():对传递的数据做"清理"和自定义验证f.is_bound:检查是否绑定数据,可以通过字典传递数据f.is_valid():验证指定的数据是否有效并符合规则f.add_error(field, error):向表单特定字段添加错误信息f.has_error(field, code=None):判断某个字段是否具有指定 code 的错误f.has_changed():检查表单的数据是否从初始数据发生改变f.changed_data:有变化的字段的列表f.fields.values():访问表单的字段但是是对象,最好使用f.cleaned_dataprint(f):即f.as_table()将 Form 渲染成 HTML 代码,还有f.as_p()与f.as_ul()
1.7 中间件
一个插件系统,嵌入在 Django 的 Request 和 Response 之间执行,可以对输入和输出内容作出修改,它是处理所有请求与响应的通用框架组件。本质上是一个 Python 类,类里定义了一些函数,这些函数在视图函数执行的前后调用。Django 默认自带中间件。
可以通过中间件来修改被传送到视图函数中的 HttpRequest 对象,也可以修改视图函数返回的 HttpResponse 对象。
1.8 Cookie 与 Session
HTTP 是一种无状态的传输协议,对于事务处理没有记忆能力,对于客户端浏览器发出的请求,Web 服务器无法区分是不是源自于同一个浏览器,所以需要额外的数据用于维持会话。
Cookie 保存在客户端浏览器存储空间中并以键值对的形式进行存储,也就是说 Cookie 也是一个类字典对象。
Session 又名会话控制,它的根本作用是在服务器上开辟一段空间用于保留浏览器和服务器交互时的会话信息。Session 是一种服务器端的机制,由服务端生成,并且保存在服务器端的内存或者缓存中,也可以是硬盘或数据库中。
工作流程:假设用户没有手动删除浏览器 Cookie,Cookie 也还未过期,初次访问时服务器会为客户端浏览器创建一个 Session 并且生成一个 SessionId,通过 HttpResponse 响应将 SessionId 发送给浏览器,浏览器接收后会将这个具有标识性的 SessionId 保存在 Cookie 中。再次访问的时候由 Cookie 携带着它去访问服务器,用户不需要输入用户名和密码就可以进入网站。
SessionId 本质上是一个加密的字符串,具有唯一性与不可重复性。这就相当于服务器给浏览器发放了一张令牌或者通行证,告诉浏览器下次再访问的时候拿着通行证来,这就解决了 HTTP 的无状态、无记忆的问题。
1.9 缓存系统
缓存是指保存一些计算开销较大的数据,减少数据库访问次数。不用每次都到数据库中读取数据,从而优化了网页的访问速度,减小 Web 服务器的压力。
Django 支持多种缓存类型,可以根据实际情况来选择用哪种类型,例如 Memcached、数据库、文件系统等。
Python 操作 Memcached 的依赖库,最常用的是 python-memcached 和 pylibmc。另外一种选择是 Redis,它是基于内存的缓存型数据库。
1.10 信号机制
适用场景
通知是信号中最常用的场景。比如当一个用户登录成功后,给该用户发送通知消息;当发布的动态有其他用户评论的时候,也可以使用信号来通知你;可以使用信号来完成对缓存的更新,每当数据表更新完成后,就发送信号通知回调函数完成更新缓存的操作。
不适用的场景
耗时任务——由于信号是同步执行的,因此耗时的任务会影响服务体验,所以此时需要考虑使用异步任务而不是信号机制。
相关设计模式:观察者模式
观察者设计模式定义了对象之间一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都获取到通知并发生相应的改变。观察者模式还有一个别名叫做发布订阅模式。
相关语言特性:弱引用
Python 的垃圾回收由引用计数、标记清理和分代回收等方式构成。其中大部分对象的生命周期由对象的引用计数来管理。引用计数有一个明显的缺点就是无法解决循环引用的问题,即 a 引用 b,b 引用 a,这样就会导致内存无法释放,也浪费了系统内存。
Python 提供了 weakref 即弱引用,它的效果是:当对一个对象创建了弱引用时,对象的引用计数不会增加。
Django 信号机制采用弱引用的方式对信号回调函数进行引用,以此来避免内存泄露的问题。Django 信号机制还应用了 Python 线程的同步机制,也就是使用锁即 Lock 来避免多线程程序中对共享资源的竞争导致的错误。
1.11 单元测试
Django 单元测试使用的是 Python 标准库 unittest 模块来定义相应的测试用例。其实就是对模块、类、函数实现的功能执行检测,看看是否满足预期,是否达到功能要求。unittest 单元测试框架中的 TestCase 类提供了很多断言方法,便于检验测试是否满足预期结果,并能在断言失败后抛出失败的原因。
断言:即开发人员会在某些特定点做出一些假设,来判断程序是否达到预期。
1.12 部署相关
WSGI 协议
一个 Web 项目的运行离不开 Web 服务器,需要一种规范或者协议来定义 Web 应用如何与 Web 服务器之间实现交互以及请求的接收与响应的返回,这就引出了 WSGI 协议。
WSGI(Web Server Gateway Interface)即 Web 服务器网关接口,它属于一种规范协议:
- 让 Web 服务器知道如何去调用 Python 应用程序
- 让 Python 应用程序知道客户端在请求什么,以及如何返回结果给 Web 服务器
Nginx
Nginx(engine x)是一个高性能的 HTTP 和反向代理 Web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。由俄国的程序设计师伊戈尔·赛索耶夫用 C 语言开发。作为一款轻量级的 Web 服务器、反向代理服务器及电子邮件代理服务器,它以自身的稳定性、并发能力强和超低的系统资源消耗而闻名。
主要作用:
- 作为 Web 服务器的反向代理服务器
- 实现 Web 服务器的负载均衡
- 站点资源的动静分离
反向代理服务器:位于客户端用户与目标服务器之间,但对于用户而言,反向代理服务器就相当于目标服务器。即用户直接访问反向代理服务器就可以获得目标服务器的资源,同时用户不需要知道目标服务器的地址。反向代理服务器通常可用来作为 Web 加速,提升用户访问站点的速度。所以使用 Nginx 作为 Web 服务器的前置服务器可以降低网络和服务器的负载,从而提高访问效率。
负载均衡(Load Balance):将工作任务分摊到多个操作单元上进行执行,比如 Web 服务器、FTP 服务器、企业关键应用服务器和其他关键任务服务器等,从而共同完成工作任务。单个服务器解决不了时,增加服务器的数量,然后将请求分发到各个服务器上面。
动静分离:把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低单个服务器的压力,可以加快网站的解析速度,提升整个服务访问性能和可维护性。
二、实战:BookStore 项目
2.1 项目初始化
创建虚拟环境:
|
|
激活虚拟环境:
- Windows:切换到
LearningDjango\Scripts目录,执行activate.bat或Activate.ps1
在 VSCode 中选择解释器:按下 Ctrl + Shift + P,选择刚创建的虚拟环境对应的 Python 解释器。
安装依赖:
|
|
新建项目:
|
|
修改数据库配置,将默认 sqlite 改为 mysql:
|
|
为了使用 MySQL 的驱动,在主应用 myBookStore 的 __init__.py 文件中加入:
|
|
2.2 用户系统开发
创建 users 应用
来到 LearningDjango\myBookStore 目录下执行:
|
|
将 users 添加到配置文件的 INSTALLED_APPS 中:
|
|
设计模型
先抽象出一个 BaseModel(基本模型),因为数据表有共同的字段,可以把它抽象出来,比如 create_time(创建时间)、update_time(更新时间)、is_delete(软删除)。
切换到 LearningDjango\myBookStore 路径下创建文件夹 db,然后创建文件 base_model.py:
|
|
别忘了在该目录下创建 __init__.py 文件。
然后针对 users 设计用户表,切换到 LearningDjango\myBookStore\users 路径下将下面的内容写入 models.py:
|
|
创建工具模块
切换到 LearningDjango\myBookStore 路径下创建文件夹 utils,然后创建文件 get_hash.py:
|
|
别忘了在该目录下创建 __init__.py 文件。
数据库迁移
|
|
前端模板与静态资源
切换到 LearningDjango\myBookStore 路径下创建文件夹 templates 和 static。
在 templates 目录下创建 users 文件夹,将 register.html 拷贝到 templates\users 下;将 js、css、images 文件夹拷贝到 static 文件夹下,作为静态文件。
将 templates 的路径写入配置文件中(注意需要 import os):
|
|
改一下 HTML 文件中的路径,将所有静态文件的路径前面加上 /static/,然后在配置文件中加入调试时使用的静态文件目录:
|
|
视图与路由配置
视图文件 users/views.py:
|
|
主应用路由 myBookStore/urls.py:
|
|
注意:原笔记中
include的参数写的是'user.urls',但实际创建的 app 名为users,此处已修正为'users.urls',app 名称也应为'users'
应用级路由 users/urls.py:
|
|
注意:原笔记此处导入了已弃用的
from django.conf.urls import url,但实际使用的是path(),此处已移除多余导入
注册表单处理
注册页面的提交表单处理流程:
- 接收前端传过来的表单数据
- 校验数据
- 写入数据库
- 返回注册页(因为还没做首页)
|
|
注意:
register_handle视图目前未做请求方法判断,建议在实际使用时加上if request.method == 'POST':的判断,GET 请求应重定向回注册页面
运行服务
|
|
若 9000 端口不行就改为其他的试试,访问链接 http://127.0.0.1:9000/user/register/
其他依赖
后续开发中可能用到的额外依赖:
|
|
django-tinymce:富文本编辑器组件Pillow:Python 图像处理库,用于处理图片上传等功能
拓展与后续学习建议
- Django 认证系统深入:本项目的用户系统是手动实现的,建议学习 Django 内置的
django.contrib.auth模块,掌握User模型、authenticate/login/logout等内置方法,以及LoginRequiredMixin等权限控制工具 - 密码安全进阶:本笔记使用 SHA-1 做哈希,而 Django 内置使用 PBKDF2 + SHA256,并支持 bcrypt、argon2 等算法。SHA-1 已被认为不够安全,生产环境应使用 Django 默认的密码哈希方案
- Django 表单与 ModelForm:本项目的表单校验手动编写,建议学习 Django Form 和 ModelForm,可以自动生成 HTML、自动校验、自动显示错误信息,大幅减少重复代码
- 基于类的视图(CBV):进一步学习 Django 内置的通用视图如
ListView、DetailView、CreateView、UpdateView等,可以用更少的代码完成常见的 CRUD 操作 - 前后端分离:了解 Django REST Framework,将后端改造为 API 服务,搭配 Vue/React 等前端框架
- Django 信号实践:在实际项目中利用信号实现用户注册后的欢迎邮件发送、缓存自动更新等功能
- 部署方案:学习 Nginx + Gunicorn/uWSGI + Django 的经典部署架构,以及 Docker 容器化部署
- 官方文档与教程:Django 官方文档 和 Django Girls 教程 是最权威的参考来源
优化要点总结
| 优化维度 | 具体操作 |
|---|---|
| 事实修正 | 修正了 include 中 user.urls → users.urls 的应用名不一致问题;移除了多余的 from django.conf.urls import url 导入;补充了 import os 提示;补充了 register_handle 缺少请求方法判断的警告;为尾部零散的 pip install 命令补上了用途说明 |
| 逻辑重构 | 将"介绍"部分按 Django 架构层次重新组织为 12 个子章节:项目结构 → URL 路由 → 视图层 → 模板系统 → 模型与 ORM → 表单系统 → 中间件 → Cookie/Session → 缓存 → 信号机制 → 单元测试 → 部署;实战部分按开发流程组织为 8 个步骤 |
| 归并去重 | 将散落的 URL 相关知识(URL 语法、反向解析、命名空间、include)归入同一章节;信号机制、观察者模式、弱引用归入同一章节 |
| 内容保留 | 原笔记中所有知识点、代码注释、数据、说明均已保留,包括 SHA-1 哈希实现、Memcached 依赖库名称、正则表达式等细节 |
| 排版规范 | 大幅减少了加粗使用,仅保留少量核心术语的加粗;移除了章节标题的粗体标记;未使用 Emoji;用引用块和缩进区分说明性文字 |
| 增值补充 | 末尾新增"拓展与后续学习建议"独立章节,涵盖认证系统、密码安全、表单优化、CBV、前后端分离、部署方案等方向,与原有内容严格分离 |