django ORM模型的数据库操作
聚合函数:
from django.db.models import Avg,Count,Max,Min,Sum
from django.db import connection
求表中一个字段的平均值:
result = 表名.objects.aggregate(Avg("字段名")) #聚合函数要放在aggregate、annotate方法里面,Avg求平均值
result的结果是一个字典,他的key是表名__聚合函数名,{"表名__聚合函数名":"xxx"}可以自己定义他的key:
result = 表名.objects.aggregate(avg = Avg("字段名"))
此时 result的结果就是{"avg":"xxx"}
print(connection.queries) #打印SQL语句,aggregate返回结果是个字典,不能直接使用query
多表联合求多个分类平均值:
results = 表名.objects.annotate(Avg("关联字段名"))
for result in results:
print(result.avg)
求表中有多少条数据:
result = 表名.objects.aggregate(nums = Count("字段名"))
result = 表名.objects.aggregate(nums = Count("字段名",distinct=True))
#distinct=True去掉重复数据
求表中最大值、最小值:
result = 表名.objects.aggregate(nums = Max("字段名"),Min("字段名"))
求表中的总和:
result = 表名.objects.aggregate(nums = Sum("字段名"))
F表达式:
给字段每个值都加10
from django.db.models import F
表名.objects.update(xxx =F("字段名")+10)
查看一张表中两个字段相同值的数据
results=表名.objects.filter(字段名1 =F("字段名2"))
for result in results:
print(result.字段名1,result.字段名2)
Q表达式:~Q取反
from django.db.models import Q
在表中查询字段名1=xx或者字段名2=yy的数据
results=表名.objects.filter(Q(字段名1=xx) | Q(字段名2=yy))
在表中查询字段名1=xx并且字段名2=yy的数据
results=表名.objects.filter(Q(字段名1=xx) & Q(字段名2=yy))
在表中查询字段名1=xx并且字段名2不包含yy的数据
results=表名.objects.filter(Q(字段名1=xx) &~Q(字段名2__icontains="yy"))
filter是将满足的拿出来,exclude是将满足的过滤掉,annotate给模型添加新的字段,比如图书表中查询的时候添加一个作者字段,可以是F/Q/或者函数等
results = 表名.objects.filter(字段名1__get=xxx).filter(~Q(字段名1=xx))
#或者
results = 表名.objects.filter(字段名1__get=xxx).exclude(字段名1=xx))
#找出字段名大于等于xxx再过滤字段名不等与xx的数据
order_by指定将查询结果进行排序
#根据创建时间正续排序
result = 表名.objects.order_by("创建时间字段")
#根据创建时间倒续排序
result = 表名.objects.order_by("-创建时间字段")
#根据字段名称排序
result = 表名.objects.order_by("字段")
#创建时间相同,再根据字段排序
result = 表名.objects.order_by("创建时间字段","字段") #这个注意点是不能出现多个order_by,否则会打乱之前的排序
values用来指定在提取数据
result = 表名.objects.values("字段名1","字段名2") #结果是一个字典
result = 表名.objects.values("字段名1","字段名2",自定义字段=F("关联表__字段")) #查询出字段名1,字段名2和关联表中的关联字段
result = 表名.objects.values() #没有传值进去的话 会返回所有字段形成字典
values_list和values的使用方法是一样的,返回结果是一个元组
result = 表名.objects.values_list("字段名1","字段名2") #结果是一个元组
result = 表名.objects.values_list("字段名1",flat = True) #flat = True 扁平化处理,返回的就是一个字符串,注意是传值只能是一个,才可以使用flat = True
all获取ORM模型的QuerySet对象 # 不建议使用,消耗数据库性能
results = 表名.objects.all()
for result in results:
print(result.字段名)
select_related 在提取模型数据的同时,也提前将相关联的数据提取出来,不能解决多对一和多对多的关系问题,只能是外键关联查询
results = 表名.objects.select_related("关联表字段名") #这里的参数可以是多个
for result in results:
print(result.关联表字段名.字段名)
prefetch_related 使用方法和 select_related 相似,解决多对一和多对多的关系问题
results = 表名.objects.select_related("字段名")
for result in results:
print(result.字段名.字段名)
defer过滤一些字段,返回的是模型
results = 表名.objects.defer("需要过滤的字段名") #id是必须提取的就算不写
only只提取某几个字段
results = 表名.objects.only("需要提取的字段名") #id是必须提取的就算不写
get获取满足某个条件的值,值是模型,但是只能是返回一条数据,没有返回会报错,返回多个也会报错
result = 表名.objects.get(pk=1) #pk是主键,比如id=1
create 创建一条数据并保存到数据库中
result = 表名.objects.create(字段名 = "值") #其效果就是在表中的字段加一条数据,并返回这个数据
#相当于执行了result = 表名(字段名 = "值")
# result.save()
get_or_create 根据某个条件进行查找,有数据就返回,没有创建数据之后返回,返回的是一个元组。前面是对象,后面是True或者False。 True创建,False是找到返回
result = 表名.objects.get_or_create(字段名 = "值")
print(result[0])
#一般是用于定义关联模型被删除之后的默认值default = result
bulk_create 一次性创建多个数据
result = 表名.objects.bulk_create([
表名(字段名 = "值"),
表名(字段名 = "值1"),
])
count 获取指定条件数据的个数,也可以使用len(字段名),但是推荐count
如:用len results = 表名.objects.all()
print(len(results))
result = 表名.objects.count()
first 返回 QuerySet 的第一条数据
result = 表名.objects.first()
last 返回 QuerySet 的最后一条数据
result = 表名.objects.last()
exists 判断某个条件下的数据是否存在。最高效的数据,返回的是 True 和 False 存在是 True
result = 表名.objects.filter(字段名1__get=xxx).exists()
distinct 去掉那些重复数据,但是不接受参数,是数据库底层计算的
results = 表名.objects.filter(字段名1__get=xxx).distinct()
update 执行跟新所有满足条件的数据
result = 表名.objects.update(字段名 = F("字段名")+5)
dalete 删除所有满足条件的数据,注意外键连接的删除
results = 表名.objects.filter(字段名1__get=xxx).dalete()
切片操作:获取前两个数据
result = 表名.objects.get_queryset()[0:2] #或者result = 表名.objects.all()[0:2] 这两个是一样的操作
for result in results:
print(result.字段名)
根据已经有的表来形成模型:
通过在终端到项目目录执行 python manage.py inspectdb 就会转换为模型显示在终端,数据少可以复制粘贴
数据多可以是用一下命令进行写入指定文件中
python manage.py inspectdb > models.py
修正:
1.可以改表名称,也就是可以改模型名称,但是在Meta中的db_table='表名'这个是不能修改的,也可以更改关联的删除的约束,删除多对多产生的模型。
2.把该文件中的代码放到对应的app中
3.更改不同app的表之前的外键引用,改造多对多的关联关系多对对的中间表表名和数据库的不同会报错,解决办法:修改数据库表名称或者是使用
db_table='表名称'来指定和数据库一样的表明称
4.将模型中的managed = Falses删除之后django才能管理
5.生成迁移脚本
6.执行一下代码,--fake-initial标记指定app的已经完成,一次只能有一个app,应为有中间表
python manage.py app1 --fake-initial
7.最后执行数据映射,是应为之前没有django的内置表