Day/6
数据库:
MVT的Mode1中内嵌了ORM框架,它将数据库与相应的对象建立关联("O:类对象R:关系数据库中数据表M:映射")即:ORM通过类和类对象就能操作它所对应的表格中的数据,且根据创建的类自动帮我们生成数据库中的表格
数据库中的表-->类
数据库中的行->对象
数据库中的字段-->属性
案例演示:
#1.在子应用的models.py文件中定义模型类
python
from django.db import models
#准备书籍列表信息的模型类
class BookInfo(models.Model):
#创建字段,字段类型,··
name = models.CharField(max_length=20,verbose name=')
pub_date = models.DateField(verbose_name = '发布日期',null=True)
readcount = models.IntegerField(default=o,verbose name = '阅读量')
commentcount = models.IntegerField(default=0,verbose name = '')
is_delete = models.BooleanField(default=False,verbose name = '逻辑别除')
#数据库个性化设置
class Meta:
db table='bookinfo'#指明数据库表名
verbose name='图书'#在admini站点中显示的名称
def str (self):
#定义每个数据对象的显示信息
return self.name
class PeopleInfo(models.Model):
GENDER CHOICES = (
(0,'male'),
(1,'female'),
)
name = models.CharField(max_length=20,verbose_name='名称')
#SmallIntegerField他的值范围ie比较小,节省内存,提升性能
gender = models.SmallIntegerField(choices=GENDER_CHOICES,default=0,verbose_name='性别')
description = models.CharField(max_length=200,null=True,verbose_name='描述信息')
book = models.ForeignKey(BookInfo,on_delete=models.CASCADE,verbose_name='图书')
is delete = models.BooleanField(default=False,verbose_name='逻辑删除')
class Meta:
db table 'peopleinfo'
verbose name='人物信息'
def __str__(self):
return self.name
"重点内容":
1.定义模型
1-1.必须继承Model类,例如class BookInfo(model.Mode1):
1-2.通过db table指明数据库表名#默认以小写app应用名小写模型类名为数据库表名
1-3.定义属性的格式是:属性=models.字段类型(选项)
1-4.django会自动生成一个主键,默认的列属性为id,可以使用primary._key设置
2.关于属性命名限制
2-1.不能是Python和MySQL的关键字,例如class、desc
2-2.不能使用连续的下划线,因为它和模型的查询语法有冲突 #可以使用单下划线
2-3.定义属性时需要指定字段类型
3.关于字段类型、选项 #不需要死记,用的时候查
3-1.CharField() 必须设置 max_length 长度
3-2.null 是否为空 null=True #例如忘记了时间
3-3.unique 唯一 unique=True #例如身份证是不能重复
3-4.default 设置默认值 default=0 #例如阅读量、评论量默认为0
4.关于数据库表的个性化设置
4-1.在模型类中通过"内嵌类"class Meta设置模型的元数据 #固定写法,注意缩进!
4-2.官方文档:Model metadata is"anything that's not a field"; 翻译即"在model里设置的meta类是对模型的基础描述,与具体的字段无关"
4-3.参数非常多,但是没一个是必需的!想怎么改自己选 #例如db_table、verbose_name、indexes
5.关于外键的参数
5-1.定义外键通过models.ForeignKey()
5-2.通过on_delete选项指定主表别除时,外键引用表数据如何处理
5-3.常用三个参数(官方文档介绍了很多):
CASCADE级联 写法:on_delete=models.CASCADE #全删
PROTECT保护 写法: on_delete=models.PROTECT #阻止删除并抛出异常
SET_NULL 写法: on_delete=models.SET_NULL, null=True #仅在该字段设置null=True时可用
6.关于枚举类型
6-1.通过choices存储一个有序字典#写法固定!注意是有序字典!
6-2.小括号中第一个元素是要在模型上设置的实际值,第二个元素是人类可读的名称
例如:
6-3.通常会设置默认值default #例如性别,可以默认是男,用户可以自行选择女
GENDER_CHOICES(
(0,'male'),
(1,'female')
)
#总结数据库和模型类
1.上面两节己经完成了模型的字段创建,工程数据库的配置,在setting文件中修改指定数据库,在主文件里的__init__文件中添加
import pymysql
pymysql.install as MySQLdb()
2.安装MySOL数据库驱动
2-1.pip install PyMySQL
3.执行数据迁移
3-1.生成迁移文件:python manage.py makemigrations
3-2.同步到数据库:python manage.py migrate
4.在MySOL数据库执行添加测试数据命令#注意添加的字段和模型类里定义的字段必须一模一样,香则会出问题!
https://www.cnblogs.com/jingzaixin/p/8670094.html
shell工具、数据库操作:
"问题":为了新手高效的学习数据的增删改查,django提供了一个shell工具,可以直接测试python代码
"shell工具的使用":
1、进入终端的虚拟环境,执行python manage.py shell
2、必须导入模型类 from users.models import BookInfo, PeopleInfo
3、ctrl+d退出,退出后需要重新导入模型类
增:
1、book = BookInfo(name='Django入门', pub_data='2022-9-20')
book.save()
2、BookInfo.objects.create(name='Django入门', pub_data='2022-9-20')
改:
1、book = BookInfo.objects.get(id=1)
book.readcount = 70 #readcount为其中一个参数值
book.save()
2、BookInfo.objects.filter(id=1).update(readcount=100,commentcount=200)
删:
1、
book = BookInfo.objects.get(id=2)
book.delete()
2、BookInfo.objects.filter(id=3).delete()
查:
1、基本条件查询 语法固定 模型类.objects.get/all/count()
1、查单个
BookInfo.objects.get(id=3) 如果查不到则报错
2、查多个
BookInfo.objects.all() 返回一个查询集
3、查数量
BookInfo.objects.count() 返回数量
2、过滤条件查询
1、表达式语法格式: 属性的名称__比较运算符=值 # 两个下划线
2、模型类.objects.filter(表达式) 返回查询集
exact 精确查询 判断相等 表达式写法 属性__exact = 参数 例如 id__exact = 1
BookInfo.objects.filter(id__exact = 1)
contains 模糊查询 表达式写法 属性__contains = 参数 例如:name__contains ='D'
BookInfo.objects.filter(name__contains ='D' ) 查询name中有D的数据集
isnull 返回为空的 表达式写法 属性__isnull = True 例如:name__isnull = True
BookInfo.objects.filter(name__isnull=True)
startswith~endswith 以指定值开头或结尾 例如:name_endswith='部'
BookInfo.objects.filter(name_endswith='部')
in 范围查找 例如:id__in = [1,3]
BookInfo.objects.filter(id__in = [1,3])
gt 大于
BookInfo.objects.filter(id__gt = 2)
gte 大于等于
BookInfo.objects.filter(id__gte = 2)
lt 小于
BookInfo.objects.filter(id__lt = 2)
lte 小于等于
BookInfo.objects.filter(id__lte = 2)
year 查年份 year、month、day、week_day、hour、minute、second
BookInfo.objects.filter(pub_data__year = 2022)
3、模型类.objects.exclude(表达式) 排除点符合条件的剩下的结果
4、模型类.objects.get(表达式) 返回一个单一的对象
"如何比较两个属性":django.db.models中定义好了两个对象G对象,F对象, 他们实现属性的比较
1、F对象 from django.db.models import F
作用:两个属性之间的比较
语法格式:(固定写法):模型类.objects.filter(属性名称1__比较运算符=F('属性名称2'))
使用F对象时,需要进行导入 from django.db.models import F
多个条件:
同时达到
1、BookInfo.objects.filter(id__gt = 2).filter(readcount__gt = 20)
2、BookInfo.objects.filter(id__gt = 2, readcount__gt = 20)
例如F对象对于或要求无法实现, 需要用到Q对象
2、Q对象
1、将多个过滤器和"逻辑非与或"组合起来使用
2、语法格式(固定写法): Q(属性名__运算符=值)
3、使用Q对象时候,需要进行导入: from django.db.models import Q
或:
BookInfo.objects.filter(Q(readcount__gt = 20)|Q(id__gt = 3))
非:
在Q前面加个~
BookInfo.objects.filter(~Q(pk=3))
聚合函数:
aggregate()过滤器调用聚合函数,聚合函数包括: Avg平均, Count数量, Max最大 ,Min最小,Sum求和,被定义在django.db.models中。
在视图函数中,通过aggregate()过滤器调用聚合函数
语法格式: 模型类.objects.aggregate(聚合函数('字段'))
例如:BookInfo.objects.aggregate(Sum('readcount'))
"注意":
1、使用count()通常不使用aggregate()过滤器
2、在使用聚合函数时,需要导入:from django.db.models import Sum/Max/Min/Avg
排序:
通过order_by对结果进行排序
语法格式:
BookInfo.objects.all().order_by('readcount') # 升序
BookInfo.objects.all().order_by('-readcount') #降序
默认是升序,若想实现降序,写成-字段
若要实现对数据的排序,使用order_by对结果进行排序,通常是和all()一起使用
关联查询:
基本关联查询:一查多
1、先拿到"一" 语法格式: 一的模型对象=一的模型类.objects.get()
2、再完成一查多 语法格式:一的模型实例对象.多的模型类名的小写_set.all()
例如:
先找出bookinfo里的一本书,通过这一本书查到另一个tables里关于这本书的人物
book = BookInfo.objects.get(id = 1)
book.peopleinfo.set.all()
基本关联查询:多查一
1、先拿到"多" 语法格式:多的模型对象 = 多的模型类名.objects.get()
2、再完成多查一 语法格式:多的模型对象.外键
例如:
通过人名查到书本名,book是peopleinfo类里面设置的外键
person = PeopleInfo.objects.get(id=1)
person.book
关联过滤查询:一查多
语法格式:多的模型类名.objects.filter(外键名__属性名__比较运算符=值)
例如:
查图书阅读量大于30的所有人物
people = PeopleInfo.objects.filter(book_readcount_gt=30)
people
关联过滤查询:多查一
语法格式:一的模型类.objects.filter(多的模型名小写__属性名__比较运算符=值)
例如:
book = BookInfo.objects.filter(peopleinfo__name='郭靖')
book
当调用如下方法时。django会返回数据集:
1、all()
2、filter()
3、exclude()
4、order_by()
查询集的两大特性:
了解概念即可
1、惰性执行
例如book = BookInfo.objects.filter(peopleinfo__name='郭靖')这一步不会访问数据库
book访问数据库
2、缓存:第一次在数据库里面查,会有缓存,后面会直接查询缓存的数据,减轻查询的压力
在实际开发中使用缓存,通过变量存储查询集,再通过for循环遍历:
#错误演示,效率特别低
for 变量 in 模型类.object.all():
print(变量)
#正确演示
变量 = 模型类.objects.all()
for a in 变量:
print(a)