010 Django ORM数据库框架
ORM数据库框架
Django 下配置 MySQL
-
ubuntu 下需要安装 mysqlclient[1.3.13 以上]
-
ubuntu 下需要确认是否安装
pythone3-dev
和defalut-libmysqlclient-dev
- 输入指令来确认您是否已经安装这些库
sude apt list --installed|grep -E 'libmysqlclient-dev|python3-dev'
- 如果没有任何输出请安装
sudo apt-get install python3-dev default-libmysqlclient-dev
- 最后我们再执行
sudo pip3 install mysqlclient
创建数据库并且让 django 使用
- 打开数据库管理工具
- 选择新建数据库
- 数据库名字最好和项目名字同名
- 在
settings.py
中修改 DATABASES 选项
- 我们的 mysql 配置项需要多一点(需要使用
pip install mysqlclient
)
了解什么是模型
- 模型是一个Python类,它是由
django.db.models.Model
派生出的子类。 - 一个模型类代表数据库中的一张数据表
- 模型类中每一个类属性都代表数据库中的一个字段
- 模型是数据交互的接口,是表示和操作数据库的方法和方式
ORM 框架
- 定义:
ORM (Object Relational Mapping)
即对象关系映射,它是一种程序技术,它允许你使用类和对象对数据库进行操作,从而避免通过SQL语句操作数据库 - 作用:
- 建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
- 根据设计的模型类生成数据库中的表格。
- 通计简单的配置就可以讲行数据库的切换
- 缺点:
- 对于复杂业务,使用成本较高
- 根据对象的操作转换成SQL语句,根据查询的结果转化成对象,在映射过程中有性能损失
模型层示例
- 此示例为添加一个bookstore_ book数据表来存放图书馆中书目信息
-
添加一个bookstore的app
python manage.py startapp bookstore
-
添加模型类并注册app
创建一个模型类
在我们新建 bookstore 文件夹下面我们有一个 models.py
文件,这个文件就是我们模型存放的地方
- 我们新建一个类,这个类要继承
models.Model
,这个类就是我们的一个数据表
class Book(models.Model):
# 标题
title = models.CharField(name="书名",max_length=50,default='')
# 创建价格max_digits精度,decimal_place小数点的位数
price = models.DecimalField(name="价格",max_digits=7,decimal_places=2,default=0)
但是此时我们现在的数据库里面还是没有这些数据的,虽然我们已经创建了,这个时候我们还需要把这些数据迁移到我们的数据库里面
数据库迁移
-
迁移是 Django 同步您对模型所做出的更改(例如添加字段,删除模型等) 到您的数据库的方法
- 生成迁移文件
python manage.py makemigrations
- 将应用下面的 models.py 文件生成一个中间文件,然后保存在 migrations文件内,但是这个时候我们实际上还是没有生效,而是存在了 应用内 migrations 文件夹内
- 我们需要进一步使用命令让他生效
- 执行迁移脚本程序
python manage.py migrat
- 执行迁移命令来迁移我们的脚本到我们的数据库中,同时将每一个应用下面的 migrations 目录中的中间文件同步回到数据库
- 生成迁移文件
-
此时我们再去查看数据库就会发现我们的数据里面已经有数据了
ORM 数据库基础字段类型
BooleanField() 布尔类型
- 数据库类型: tinyint(1) ,数据库中 1代表 true,0代表false
CharField() 字符串类型
- 数据库类型: varchar
- 注意:必须要指定
max_length
的参数值
DateField() 时间类型
- 数据库类型:date
- 参数:
- auto_now: 每次保存对象的时候,自动设置该字段为当前时间
- 参数值 True or False
- 当对象被存储时自动将对象的时间更新为当前时间,可以用来比如说博客的最近更新中。当执行
Model.save()
操作时自动更新,但当通过其他的途径比如QuerySet.update()
更新其他的内容时,它不会自动更新
- auto_now_add:当对象第一次被创建的时候自动设置当前时间
- 参数值 True or False
- 储存当对象被创建时的时间,可以用来存储比如说博客什么时候创建的,后来你再更改博客,它的值也不会变
即使你指定了默认值,它还是会忽略你的存在而依然我行我素
- default: 设置当前时间
default=date.today
(来源:date.date.today()
)
- auto_now: 每次保存对象的时候,自动设置该字段为当前时间
- 以上三个参数只能3个选取其中一个,无法全部选择
DateTimeField() 更加精确的时间类型
-
数据库类型:datetime(6)
-
参数:
-
auto_now: 每次保存对象的时候,自动设置该字段为当前时间
- 参数值 True or False
- 当对象被存储时自动将对象的时间更新为当前时间,可以用来比如说博客的最近更新中。当执行
Model.save()
操作时自动更新,但当通过其他的途径比如QuerySet.update()
更新其他的内容时,它不会自动更新
-
auto_now_add:当对象第一次被创建的时候自动设置当前时间
- 参数值 True or False
- 储存当对象被创建时的时间,可以用来存储比如说博客什么时候创建的,后来你再更改博客,它的值也不会变
即使你指定了默认值,它还是会忽略你的存在而依然我行我素
-
default: 设置当前时间
default=timezone.now
(来源:django.utils.timezone.now()
)
-
-
以上三个参数只能3个选取其中一个,无法全部选择,当你把它仨或者其中的俩放一块儿就会报错
DecimalField() 小数类型
- 数据库类型:decimal(x,y)
- 参数:
max_digits
位数的总个数,比如你填6,那么整数加上小数一共6位(该值必须大于decimal_places
)decimal_places
小数点后的数字数量
EmailField() 邮箱类型
- 数据库类型:varchar
- 我们的 django 给我内置了特殊的正则,虽然存入数据库的还是普通的 varchar 字段,但是如果没有满足我们正则的邮箱不会被我们存进去
IntegerField() 整数类型
- 数据库类型:int
- 没什么好说的,就是存入一个整数
ImageField() 图片路径
- 数据库类型:varchar(100)
- 注意:这个存进去的并非是我们的图片二进制流文件或者是图片的base64文件,而是我们图片在我们项目下的路径
TextField()
- 数据库类型:longtext
- 用来保存不定长的很大的字符数据
ORM 数据库字段选项
字段选项,指定创建的列的额外的信息
- 允许出现多个字段选项,多个选项之间使用
,
隔开
参数名 | 可选值 | 作用说明 |
---|---|---|
primary_ key | True / False | 如果设置为True,表示该列为主键如果指定一个字段为主键,则此 数库表不会创建id字段 |
blank | True / False | 设置为True时, 字段可以为空。设置为False时, 字段是必须填写的 这个并非是 mysql 内的 null , 这是空字符串,例如 ‘’ ,虽然是空字符串,但是依旧是一个字符串,并非完全是空 |
null | True / False | 如果设置为 True,表示该列的值允许为空 官方建议减少使用 null ,取而代之的是使用 default |
default | 字符串 / 数字 | 设置所在列的默认值,如果你没有添加数据 django 就会默认帮你添加 |
db_index | True / False | 如果设置为 True,表示为该列增加索引 增加索引会加快查找速度但是会降低数据插入和修改速度 |
unique | True / False | 如果设置为True,表示该字段在数据库中的值必须是唯一(不能重复出现的) |
db_column | 字符串 | 指定列的名称,如果不指定的话则采用属性名作为列名 |
verbose_name | 字符串 | 设置此字段在admin界面上的显示名称 |
例子
#创建一个属性,表示用户名称,长度30个字符,必须是唯一的,不能为空,添加索引
name = models.CharField(max_length=30, unique=True, null=False, db_index=True)
练习
class Book(models.Model):
# 标题
title = models.CharField(name="书名",max_length=50,default='',unique=True)
# 出版社
pub = models.CharField(name="出版社",max_length=100,null=False,default='')
# 创建价格max_digits精度,decimal_place小数点的位数
price = models.DecimalField(name="价格",max_digits=7,decimal_places=2,default=0)
market_price = models.DecimalField(name="零售价",max_digits=7,decimal_places=2,default=0)
class Author(models.Model):
# 姓名
name = models.CharField(name="姓名",max_length=20,null=False,default='')
# 年龄
age = models.IntegerField('年龄',default=1)
# 邮箱
email = models.EmailField('邮箱',null=True)
-
执行命令
python manage.py makemigrations
-
执行命令
python manage.py migrate
-
最终回到数据库,可以看到我们现在已经有了更多的选项了
Meta 类自定义我们的表
修改我们的表名
我们默认的表名是我们的应用名字 + 我们的类名
,例如 bookstore_book,我们可以通过定义一个 Meta 类来修改我们的表
class Book(models.Model):
# 标题
title = models.CharField(name="书名",max_length=50,default='')
# 创建价格max_digits精度,decimal_place小数点的位数
price = models.DecimalField(name="价格",max_digits=7,decimal_places=2,default=0)
- 修改我们的表名
class Book(models.Model):
# 标题
title = models.CharField(name="书名",max_length=50,default='')
# 创建价格max_digits精度,decimal_place小数点的位数
price = models.DecimalField(name="价格",max_digits=7,decimal_places=2,default=0)
# 修改我们的表名
class Meta:
db_tablle = "book"
此时我们的表名已经变成了 book
修改我们在后端 admin 中显示的名字
- 此章节请看完
012 admin后台管理
再前来观看
我们的后台默认名字是我们表的名字,我们希望可以让他显示其他的名字,我们就可以用到Meta 方法中的 verbose_name
和 verbose_name_plural
-
verbose_name 可以直接修改我们在 admin 上的名字
-
class Meta: verbose_name = "图书"
-
-
因为 django 是美国人的东西,他们会在名字后面加上复数,我们可以使用另一个参数 verbose_name_plural 来让他的单复数同形
-
class Meta: verbose_name = "图书" verbose_name_plural = verbose_name
-
常见错误
数据库的迁移文件混乱的解决方法
数据库中django_migrations 表记录了migrate的‘全过程’,项目各应用中的migrate文件应与之对应,否则migrate会报错
- 解决方法
- 删除所有 migrations 里的
000?_XXXX.py
(小心不要删除__init__.py
)
- 清空数据库
- 重新使用
makemigrations
和migrate
命令
- 删除所有 migrations 里的