上一章的 Django 请求响应流程中,我们简单地返回了一个字符串供前端显示。但是在实际情况下,总会有大量的动态数据需要储存和使用,比如文章的标题和正文、用户的名称和密码等。
存储这些数据需要专门的地方,被称为数据库。
本章就来了解下如何在 Django 中使用数据库。数据库与模型数据库是存储信息的场所。数据库由多个数据表构成。
啥意思?举个栗子,三年级二班中同学名册就是数据表。
有的名册记录每位同学的考试成绩、有的记录身高体重、还有的记录兴趣爱好...所有的这些名册都放在老师的柜子里,这个柜子就是“数据库”了。
默认情况下,数据库就是db.sqlite3这个文件了。 在网站上线后你可能想换别的数据库,不过目前还不需要讨论这个内容。操作数据库使用的是古老的 SQL 语句,它是完全不同于 Python 的另一种语言,这对新手来说无疑是困难的。幸运的是,在 Django 里写小型 Web 应用并不需要你直接去操作数据库。
你只需要用 Python 语言定义好模型,而模型会自动生成操作数据库所必要的一切。
这叫对象关系映射(Object Relational Mapping,简称ORM),用于实现编程语言里不同类型系统的数据之间的转换。光讲理论有点枯燥,接下来通过实践理解。编写模型Photo App 中的
models.py
就是编写模型的地方。将其修改如下: # /photo/models.py from django.db import models from django.utils.timezone import now class Photo : image = models . ImageField created = models . DateTimeField def __str__ : return self . image . name
继承自 models.Model
的对象被称为模型类,它对应了数据库中的数据表。模型类中可以定义很多字段,字段对应数据表中的不同信息。
比如名册,里面每个同学都有姓名、年龄,在数据库中就是姓名字段、年龄字段等。
Photo
模型中仅有两个字段。ImageField
字段用于存储图片信息。通常来说,字段中会存储对应数据,比如 CharField
会将字符数据保存在数据库中。但 ImageField
有点特殊,因为图片作为一种文件,直接保存在硬盘中就足够了,并不需要真正放进数据库中。因此 ImageField
实际上只在数据库中保存了图片的名称、存储路径、索引等元数据,真正的图片文件被保存在 upload_to
参数所指定的路径中。
另外一个'photo/%Y%m%d/'
是动态格式化当前日期的特殊书写方式。比如今天是2021年8月5日,那么图片将被保存在项目路径下的/photo/20210805/
文件夹中。
DateTimeField
用于记录图片创建的时间,默认值为当前时间。方法 __str__
用于美化模型在后台、命令行中的输出信息。接下来要修改 # /album/settings.py ... INSTALLED_APPS = [ 'django.contrib.admin' , '... # 注册App 'photo' , ] ... # 指定媒体文件路径 MEDIA_URL = '/media/' MEDIA_ROOT = base_DIR / 'media'/album/settings.py
文件,这是 Django 的全局配置文件:
将 photo
添加到 INSTALLED_APPS
列表中,让 Django 程序加载这个自定义的 App。
后续进行模型迁移时,程序会在此列表中进行搜索。由于图片是媒体文件,它并不直接保存在数据库中,因此要增加
MEDIA_URL
和 MEDIA_ROOT
配置,指定这些图片上传的路径位置。此外,媒体文件表现在前端中同样也是单独的 url 路径。因此要在根路由文件 # /album/urls.py ... from django.conf import settings from django.conf.urls.static import static urlpatterns = [ ... ] + static/album/urls.py
添加对其的路径支持:
至此模型基本就写好了。
只有在开发阶段时,即接下来进行数据迁移。数据迁移数据迁移这个词听起来很玄乎,其实它有点类似于将刚才写的模型同步到数据库里。settings.py
中的DEBUG = True
时,服务器才会处理图片或.js
这类静态文件。当
DEBUG = True
时,Django 服务器将拒绝处理静态文件(由于效率低下),此时需要将其交给 nginx 进行处理。后续部署的章节将会继续讨论。
要记得数据库和 Python 是完全不同的东西,你在 Python 里写的模型长啥样,数据库并不知道。因此需要数据迁移这个步骤,Django 框架将在幕后自动为你处理好 Python 对象和数据库数据之间的对应关系。
张三(Python)有一本名册(模型类),拿给了李四(数据库)。由于李四将名册的结构(需要记录哪些信息)原封不动抄到自己的名册中(数据迁移)。
ImageField
的数据迁移依赖 Pillow
库,因此首先安装它:(一定要记得在虚拟环境中!)>
pip
install
Pillow
==
8.3
.
1
-
i
https
:
//
pypi
.
tuna
.
tsinghua
.
edu
.
cn
/
simple
...
Successfully
installed
Pillow
-
8.3
.
1
接着输入指令创建迁移文件:>
python
manage
.
py
makemigrations
# 以下为输出
Migrations
for
'photo'
:
photo
migrations
0001
_initial
.
py
-
Create
model
Photo
成功后执行迁移:>
python
manage
.
py
migrate
# 以下为输出
Operations
to
perform
:
Apply
all
migrations
:
admin
,
auth
,
contenttypes
,
photo
,
sessions
Running
migrations
:
Applying
contenttypes
.
0001
_initial
...
OK
Applying
auth
.
0001
_initial
...
OK
Applying
admin
.
0001
_initial
...
OK
...
Applying
photo
.
0001
_initial
...
OK
Applying
sessions
.
0001
_initial
...
OK
没报错就表示迁移成功了。接下来我们存储些数据看看效果。后台操作Django 开发之所以高效,原因之一就是自带很多通用功能的默认实现,比如后台管理功能。首先在命令行里创建管理员账号: > python manage . py createsuperuser Username : dusai Email address : Password : Password : Superuser created successfully . # /photo/admin.py from django.contrib import admin from photo.models import Photo admin . site . register
注意在命令行里填写密码是不会显示任何字符的。接着还需要将 Photo
模型注册到后台中。修改 /photo/admin.py
文件如下:
这就Ok了。
重新启动服务器,输入 127.0.0.1:8000/admin
路径:可以看到后台中已经有了 Photo
的管理入口。点击 Add
添加新的图片数据:保存好之后,就可以在后台中看到已经上传的图片信息了。接着到