肆拾捌 --- 模型层下
Posted tangceng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了肆拾捌 --- 模型层下相关的知识,希望对你有一定的参考价值。
django模板层下
一、聚合查询与分组查询
1.1 聚合
? 聚合函数是sql的基本函数,会对一组值执行计算并返回单一的值。
from django.db.models import Avg,Sun,Max,Min,Count
res1 = models.Book.objects.all().aggregate(Avg('price'))
res2 = models.Book.objects.all().aggregate(Max('price'))
res3 = models.Book.objects.all().aggregate(Min('price'))
res4 = models.Book.objects.all().aggregate(Sum('price'))
res5 = models.Book.objects.all().aggregate(Count('title'))
res6 = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price'),Sum('price'),Count('title'))
1.2 分组
? 分组查询使用关键字annotate()方法。
? 1.统计每一本书的作者个数:
res = models.Book.objects.annotate(author_num = Count('author')).values('author_num')
? 2.统计每个出版社卖的价格做便宜的书的价格:
res = models.Publish.objects.annotate(price_min=min(;book__price)).values('price_min')
? 3.统计不止一个作者的图书:
res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('author_num')
? 4.查询每个作者出的图书的总价:
res = models.Author.object.annotate(sun_price=Sum('book__price')).values('sum_price')
二、F与Q查询:
2.1 F查询
? jango提供的F()方法可以在查询中引用字段,比较来自同一个model中的两个不同字段的值。
from django.db.models import F
? 1.查询出卖出数大于库存数的商品:
res = models.Product.objects.filter(maichu__gt=F('kucun'))
? F可以取到表中某个字段对应的值来当作筛选条件,而不是自定义常量的条件了,实现了动态比较的效果。
? Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。基于此可以对表中的数值类型进行数学运算。
? 将每个商品的价格提高50块:
res = models.Product.object.update(price=F('price')+50)
2.2 Q查询
? filter()
等方法中逗号隔开的条件是与的关系。 如果需要执行更复杂的查询(例如OR
语句),可以使用Q对象
。
from django.db.models import Q
? 1.查询 卖出数大于100 或者 价格小于100块的:
res = models.Prodect.object.filter(Q(maichu__gt=100)|Q(price__lt=100))
? 2.查询 库存数是100 并且 卖出数不是0 的产品:
res = models.Prodect.objects.filter(Q(kucun=100)&~Q(maichu=0))
三、orm中的字段
3.1 常见字段
AutoField(Field)
- int自增列,必须填入参数 primary_key=True
BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True
注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models
class UserInfo(models.Model):
# 自动创建一个列名为id的且为自增的整数列
username = models.CharField(max_length=32)
class Group(models.Model):
# 自定义自增列
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767
IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647
BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
BooleanField(Field)
- 布尔值类型
NullBooleanField(Field):
- 可以为空的布尔值
CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度
TextField(Field)
- 文本类型
EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制
IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"
URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字
UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹
FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)
DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]]
DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
FloatField(Field)
- 浮点型
DecimalField(Field)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度
BinaryField(Field)
- 二进制类型
字段合集
3.2 字段参数
null
-用于表示某个字段可以为空。
unique
-如果设置为unique=True 则该字段在此表中必须是唯一的 。
db_index
-如果db_index=True 则代表着为此字段设置索引。
default
-为该字段设置默认值。
auto_now_add
-配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
auto_now
-配置上auto_now=True,每次更新数据记录的时候会更新该字段。
to
设置要关联的表
to_field
设置要关联的表的字段
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。
models.CASCADE
删除关联数据,与之关联也删除
db_constraint
是否在数据库中创建外键约束,默认为True。
四、查询与优化
4.1 only与defer
? only:
res = models.Book.object.all()
for i in res:
print(r.title)
? only会将括号内的字段对应的值,直接封装到返回给你的对象中点该字段,不需要再走数据库一旦你点了不是括号内的字段 ,就会频繁的去走数据库查询。
? defer:
res = models.Book.objects.defer('title') # defer和only互为反关系
for r in res:
print(r.title)
? defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中 点该其他字段,不需要再走数据库一旦你点了括号内的字段,就会频繁的去走数据库查询。
4.2 select_related和prefetch_related
? select_related 会自动做连表操作,然后将连表之后的数据全部查询出来封装给对象select_related括号内只能放外键字段,并且多对多字段不能放。如果括号内外键字段所关联的表中还有外键字段,还可以继续连表。select_related(外键字段__外键字段__外键字段...)
res = models.Book.objects.select_related('publish')
? prefetch_related看似连表操作,其实是类似于子查询prefetch_related括号内只能放外键字段 。并且多对多字段不能放 ,如果括号内外键字段所关联的表中还有外键字段,还可以继续连表 ,select_related(外键字段__外键字段__外键字段...)。
res = models.Book.objects.prefetch_related('publish')
print(res)
for r in res:
print(r.publish.name)
五、事务
? 事务的定义:将多个sql语句操作变成原子性操作,要么同时成功,有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对于事务则是部分支持)。
? 事务的四大特点:
- 原子性;
- 持久性;
- 一致性;
- 隔离性。
? django中开启事务:
from django.db import transation
with transaction.atomic():
# 在该代码块中所写的orm语句 同属于一个事务
# 缩进出来之后自动结束
以上是关于肆拾捌 --- 模型层下的主要内容,如果未能解决你的问题,请参考以下文章