CharField(Field)
字符类型. 必须指定max_length参数,max_length表示字符长度
AutoField(Field)
必须指定参数primary_key=True指定主键. 如果没有设置主键, 默认创建并以id名作为主键
IntegerField(Field)
整数类型(有符号) -2147483648 ~ 2147483647
DecimalField(Field)
十进制小数
参数:
max_digits:数据总长度
decimal_places:小数位长度
EmailField(CharField)
带邮箱正则验证,自动判断邮箱的格式
DateField(DateTimeCheckMixin, Field)
日期字段. 格式: YYYY-MM-DD. 一般指定参数auto_now=Ture更新记录的时间, 或者auto_now_add=True插入记录的时间
DateTimeField(DateField)
日期字段. 格式: YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 一般指定参数auto_now=Ture更新记录的时间, 或者auto_now_add=True插入记录的时间|
TextField(Field)
大量文本类型,超过254字符时替代CharField
BooleanField(Field)
布尔型、判断状态时使用,True/False,比如是否删除
FloatField(Field)
浮点数
SmallIntegerField(IntegerField)
小整型 -32768 ~ 32767
URLField(CharField)
字符串类型,为Django Admin以及ModelForm中提供验证URL
SlugField(CharField)
字符串类型,为Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
UUIDField(Field)
字符串类型,为Django Admin以及ModelForm中提供对UUID格式的验证
ImageField(FileField)
字符串,路径保存在数据库,文件上传到指定目录
参数:
upload_to=" ":上传文件的保存路径
storage=None:存储组件,默认files.storage.FileSystemStorage
width_field=None:上传图片的高度保存的数据库字段名(字符串)
height_field=None:上传图片的宽度保存的数据库字段名(字符串)
FileField(Field)
字符串类型,路径保存在数据库,文件上传到指定目录
参数:
upload_to=" ":上传文件的保存路径
storage=None:储存组件,默认files.storage.FileSystemStorage
FilePathField(Field)
字符串类型,为Django Admin以及ModelForm中提供读取文件夹下文件的功能
参数:
path:文件夹路径
match=None:正则匹配
recursive=False:递归下面的文件夹
allow_files=True:允许文件
allow_folders=False:允许文件夹
sex = models.IntegerField(choices=[(0, '女'), (1, '男'), ], default=1)
error_messages={'unique': '输入内容已存在','invalid': '输入格式错误',
}
validators import validators import EmailValidator,URLValidator,DecimalValidator,MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidatorname = models.CharField(max_length=32,validators=[RegexValidator(r'root_d+', message='错了', code="c1"),RegexValidator(r'root_11111d+', message="又错了", code='c2'),EmailValidator(message='还是错了', code='c3'), ],error_messages={'c1': '错误信息1','c2': '错误信息2','c3': '错误信息3',}
)
blank
设置为True时,字段可以为空。设置为False时,字段是必须填写的。字符型字段CharField和TextField是用空字符串来存储空值的。
null
设置为True时,django用Null来存储空值。日期型、时间型和数字型字段不接受空字符串。所以设置IntegerField,DateTimeField型字段可以为空时,需要将blank,null均设为True。如果为True,空值将会被存储为NULL,默认为False。
如果想设置BooleanField为空时可以选用NullBooleanField型字段。
一句话概括,null 是针对数据库而言,如果 null=True, 表示数据库的该字段可以为空。blank 是针对表单的,如果 blank=True,表示你的表单填写该字段的时候可以不填
一对一: 一般用于某张表的补充,比如员工表(包含姓名、性别、年龄、电话等),每个员工还有张用户表(包含关联员工表、用户名、密码、角色),一对一关联
一对多: 是最常见的一种设计。就是 A 表的一条记录,对应 B 表的多条记录,且 A 的主键作为 B 表的外键。这主要看以哪张表为中心,以上示例以 A 表为中心,就是一对多,如果以 B 表为中心,则是多对一。举几个例子:
多对多: 在数据库中也比较常见,可以理解为是一对多和多对一的组合。要实现多对多,一般都需要有一张中间表(也叫关联表),将两张表进行关联,形成多对多的形式
# 一对多,外键字段推荐建在一对多中多的一方
# Student表和 Grade 表是一对多的关系, Student 表是多,在多的一方创建外键 一个班级对应多个学生
grade = models.ForeignKey(to='Grade', on_delete=models.SET_NULL, null=True)
参数
class Student(models.Model):name = models.CharField(max_length=32)class = models.ForeignKey(to="Classes")class Classes(models.Model):name = models.CharField(max_length=32)
查询某个班级关联的所有学生(反向查询)
models.Classes.objects.first().student_set.all()
在ForeignKey字段中添加了参数 related_name
class Student(models.Model):name = models.CharField(max_length=32)class = models.ForeignKey(to="Classes", related_name="students")
查询某个班级关联的所有学生(反向查询)
models.Classes.objects.first().students.all()
必须指定one_delete级联删除策略
def func():return 10class MyModels(models.Model)fk = models.ForeignKey(to='User', to_field='id', on_delete=models.SET(func(), ))
models.SET
# 建议外键字段建立在查询频率较高的一方
# Student 和 StudentDetail 表是一对一的关系,在父表中创建,一个学生有一条详情
detail = models.OneToOneField(to='StudentDetail', on_delete=models.CASCADE)
to:设置要关联的表,即想与哪张表进行关联
to_field:指定要与关联的表中的哪一个字段进行关联,默认是和主键关联
one_delete:同上
ManyToManyField:多对多
# 建议外键字段推荐建在查询频率较高的一方,且无需手动创建中间表,models会自动帮你创建一张虚拟表
# Course 和 Student 表是多对多的关系,一个课程可以有多个学生报,一个学生也可以报多个课程,在那边设置都可以
students = models.ManyToManyField(to='Student', through='Enroll')
through_fields=('group', 'person')
class Book(models.Model):title = models.CharField(max_length=32, verbose_name="书名")class Author(models.Model):name = models.CharField(max_length=32, verbose_name="作者姓名")# 自己创建第三张表,分别通过外键关联书和作者
class Author2Book(models.Model):author = models.ForeignKey(to="Author",on_delete=models.CASCADE)book = models.ForeignKey(to="Book",on_delete=models.CASCADE)class Meta:unique_together = ("author", "book")
class Book(models.Model):title = models.CharField(max_length=32, verbose_name="书名")# 通过ORM自带的ManyToManyField自动创建第三张表
class Author(models.Model):name = models.CharField(max_length=32, verbose_name="作者姓名")books = models.ManyToManyField(to="Book", related_name="authors")
class Book(models.Model):title = models.CharField(max_length=32, verbose_name="书名")# 自己创建第三张表,并通过ManyToManyField指定关联,
class Author(models.Model):name = models.CharField(max_length=32, verbose_name="作者姓名")books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book"))# through_fields接受一个2元组('field1','field2'):# 其中field1是定义ManyToManyField的模型外键的名(author),field2是关联目标模型(book)的外键名。class Author2Book(models.Model):author = models.ForeignKey(to="Author")book = models.ForeignKey(to="Book")class Meta:unique_together = ("author", "book")
注意:
当我们需要在第三张关系表中存储额外的字段时,就要使用第三种方式。
但是当我们使用第三种方式创建多对多关联关系时,就无法使用set、add、remove、clear方法来管理多对多的关系了,需要通过第三张表的model来管理多对多关系。
class Meta:# 如果 abstract = True, 就表示模型是 抽象基类abstract = True#app_label声明属于哪个应用app_label='Students'#table_name自定义表名、如果没有指定表名会是:应用名_类名db_table='Students'#有些数据库有数据库表空间,比如Oracle。你可以通过db_tablespace来指定这个模型对应的数据库表放在哪个数据库表空间。db_tablespace = "user"#个 DateField 或 DateTimeField 字段的名字. 若提供该选项, 该模块将拥有一个 get_latest() 函数以得到 "最新的" 对象(依据那个字段): 得到最近一 条order_date字段记录、get_latest_by = "order_date" #给这个模型取一个更简单、好读的名字verbose_name = "pizza" #如果将上面的verbose_name跟verbose_name_plural设置成同样的值,就不会再admin中显示sverbose_name_plural = verbose_name# 联合索引: 索引的一个主要目的就是加快检索表中数据index_together=("grade","user")# 联合约束: 两个字段全部重复才算重复unique_together = ("grade","user")# 指定默认按什么字段排序,只有设置了该属性,我们查询到的结果才可以被reverse()。ordering="grade"
在Django项目的settings.py文件中,配置数据库连接信息:
DATABASES = {"default": {"ENGINE": "django.sql","NAME": "你的数据库名称", # 需要自己手动创建数据库"USER": "数据库用户名","PASSWORD": "数据库密码","HOST": "数据库IP","POST": "数据库端口"}
}
在Django项目的__init__.py文件中写如下代码,告诉Django使用pymysql模块连接MySQL数据库:
import pymysqlpymysql.install_as_MySQLdb()
只需要测试Django项目中某个py文件的内容,可以不必通过前端,单独进行测试即可
# 测试环境的准备 去manage.py中拷贝前四行代码 然后自己写两行
import osif __name__ == "__main__":os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django.settings.dev')import djangodjango.setup()# 在这个代码块的下面就可以测试django里面的单个py文件了(注意: 导模块也要写在这下面)# 可以使用原生sql的查询方式from django.db import connectioncursor = connection.cursor()ute('select name from students_student')print(cursor.fetchall())
1.create()
创建数据并直接获取当前创建的数据对象
# 创建方式一:
res = ate(num='1',college='第一小学')
# 创建方式二:
res = StudentDetail(num='2',college='第一小学')
res.save()
2.all()
查询所有数据,结果是QuerySet [数据对象1,数据对象2]
res = Student.objects.all()
3.filter()
根据条件筛选数据,结果是QuerySet [数据对象1,数据对象2]
res = Student.objects.filter() # 和all()一样
res1 = Student.objects.filter(name='娜美',age=18) # and的关系
4.first()、last()
QuerySet支持索引取值但是只支持正数 并且orm不建议你使用索引
res = Student.objects.filter(age=18).first() # 取queryset里的第一个数据,数据不存在不会报错而是返回None
res1 = Student.objects.filter().last() # 取queryset里的最后一个数据,数据不存在不会报错而是返回None
5.update()
更新数据(支持批量更新)
Student.objects.filter(name='路飞').update(name='lufei') # 单个更新
Student.objects.filter().update(sex=2) # 批量更新
6.delete()
删除数据(支持批量删除)
Student.objects.filter().delete() # 批量删除
Student.objects.filter(id=1).delete() # 单个删除
7.values()
根据指定字段获取数据,结果是QuerySet [{},{},{},{}]
res = Student.objects.filter().values() # 表里的所有字段
res1 = Student.objects.values() # 同上
res2 = Student.objects.all().values('name') # 表里的name字段 <QuerySet [{'name': 'lufei'}, {'name': '娜美'}, {'name': '山治'}]>
res3 = Student.objects.filter().values('name','age') # 同上
8.values_list()
根据指定字段获取数据,结果是QuerySet [(),(),(),()]
res4 = Student.objects.all().values_list('name','age') # 只有字段的值 <QuerySet [('lufei', 18), ('娜美', 18), ('山治', 18), ('索隆', 18)]>
9.distinct()
去重(数据一定要一模一样才可以,如果有主键肯定不行)
res = Student.objects.values('name','age').distinct()
10.order_by()
根据指定条件排序,默认是升序,字段前面加负号就是降序
res = Student.objects.all().order_by('-id')
11.get()
根据条件筛选数据并直接获取到数据对象 一旦条件不存在会直接报错 不建议使用
res = (id=11) #lufei-18 数据不存在会报错,不建议使用
12.exclude()
排除
res = lude(id=1) # 查询出除了id=1的其他的数据
13.count()
统计结果集中数据的个数
res = Student.objects.all().count()
14.exists()
判断结果集中是否含有数据 如果有则返回True 没有则返回False
res = Student.objects.filter(id=11).exists() # False
15.及时查看sql语句
res = Student.objects.all()
print(res.query)
只要还是queryset对象就可以无限制的点queryset对象的方法
queryset.filter().values().filter().values_list().filter()…
参数 | 释义 | 例子 | 说明 |
---|---|---|---|
__in | 是否在给定的数据集中 | res=Student.objects.filter(age__in=(18,28,38)) | 查询年龄是18或28或38的数据 |
__gt | 大于 | res=Student.objects.filter(age__gt=18) | 查询年龄大于18的数据 |
__lt | 小于 | res=Student.objects.filter(age__lt=18) | 查询年龄小于18的数据 |
__gte | 大于等于 | res=Student.objects.filter(age__gte=18) | 查询年龄大于等于18的数据 |
__lte | 小于等于 | res=Student.objects.filter(age__lte=18) | 查询年龄小于等于18的数据 |
__range | 在…之间, 闭区间 | res=Student.objects.filter(age__range=(18,38)) | 查询年龄范围在18到38之间的数据 |
__contains | 包含 | res=Student.objects.filter(name__contains=‘y’) | 查询姓名包含字母y的数据,区分大小写 |
__icontains | 包含(忽略大小写) | res=Student.objects.filter(name__contains=‘y’) | 查询姓名包含字母y的数据,不区分大小写 |
__startwith | 以…开头 | res=Student.objects.filter(name__startswith=‘lu’) | 查询姓名以lu开头的数据 |
__endwith | 以…结尾 | res=Student.objects.filter(name__endwith=‘mei’) | 查询姓名以mei结尾的数据 |
__year | 取出年份(仅限于时间类型) | res = Student.objects.filter(c_time__year=2023) | 查询创建时间是2023年的数据 |
__month | 取出月份(仅限于时间类型) | 用法同上 | |
__day | 取出日期(仅限于时间类型) | 用法同上 | |
__hour | 取出小时(仅限于时间类型) | 用法同上 | |
__minute | 取出分钟(仅限于时间类型) | 用法同上 | |
__second | 取出秒(仅限于时间类型) | 用法同上 |
from django.db import modelsclass Book(models.Model):"""图书表"""title = models.CharField(verbose_name='书名',max_length=32)price = models.DecimalField(verbose_name='价格',max_digits=8, decimal_places=2)publish_time = models.DecimalField(verbose_name='出版日期',auto_now_add=True)# 创建书籍与出版社的一对多外键字段,一个出版社对应多个书籍,书籍是多的一方,在多的一方设外键"""on_delete=models.CASECADE 设置级联级联删除,在publish删除出版社后,出版社所关联的书籍也会被删掉(在没有publish_id的那一方删除)"""publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)# 创建书籍与作者的多对多外键字段,authors = models.ManyToManyField(to='Author')class Publish(models.Model):"""出版社表"""name = models.CharField(verbose_name='名称',max_length=32)address = models.CharField(verbose_name='地址',max_length=64)class Author(models.Model):"""作者表"""name = models.CharField(verbose_name='姓名',max_length=32)age = models.IntegerField(verbose_name='年龄') # 创建作者与作者详情表之间一对一外键字段"""on_delete=models.CASECADE,在AuthorDetail表删除author表关联的数据时,author表的数据也会被删掉(在没有author_detail_id的那一方删除)"""author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)class AuthorDetail(models.Model):"""作者详情表"""phone = models.BigIntegerField(verbose_name='手机号')address = models.CharField(verbose_name='家庭住址',max_length=64)
python manage.py makemigrations books
python manage.py migrate books
import osdef main():os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django.settings.dev')import djangodjango.setup()from books import models"""创建数据的两种方式"""# 方式1:外键字段绑定要关联的id,注意外键字段之后拼接"_id"models.ate(title='三国演义',price=88.88,publish_id=1)models.ate(title='红楼梦', price=66.66, publish_id=2)models.ate(title='西游记', price=99.99, publish_id=1)# 方式2:先获取关联表中要绑定的对象,外键字段直接绑定该对象publish_obj = models.Publish.objects.filter(pk=3).first()models.ate(title='水浒传', price=77.77, publish=publish_obj)main()
add() 括号里面可以是一个或多个位置参数,支持数字和对象
"""针对多对多关系绑定的两种方式"""# 方式1:直接添加关系表中的id值book_obj1 = models.Book.objects.filter(pk=1).first() # 在book表查出要绑定的数据book_obj1.authors.add(1) # 在第三张关系表中 book_author 中给当前书籍绑定作者,(id=1)book_obj1.authors.add(2,3) # 支持一次性绑定多个# 方式2:先获取关联表中要绑定的数据对象,添加该对象book_obj2 = models.Book.objects.filter(pk=3).first()author_obj1 = models.Author.objects.filter(pk=2).first() # 获取作者对象2author_obj2 = models.Author.objects.filter(pk=3).first() # 获取作者对象3book_obj2.authors.add(author_obj1,author_obj2) # 绑定上述两个作者对象
remove() 括号里面可以是一个或多个位置参数,支持数字和对象
"""删除绑定关系"""# 方式1:book_ve(1) # 删除书籍对象book_obj1绑定的作者id值为1的关系book_ve(2,3) # 支持一次性删除多个# 方式2:book_ve(author_obj1,author_obj2) # 删除书籍对象book_obj2绑定的两个作者对象
set() 注意括号里面为可迭代对象(元组 列表),支持数字和对象
# 方式1:book_obj1.authors.set((4,)) # 本来是1对应1,修改后是1对应4,没有4的话不修改book_obj1.authors.set([4])book_obj1.authors.set((5,6)) # 本来是1对应1,修改后是1对应5,1对应6没有的话不修改book_obj1.authors.set([5, 6])# 方式2:book_obj2.authors.set((author_obj1,))book_obj2.authors.set((author_obj1, author_obj2))
clear()
book_obj1.authors.clear() # 清空book_obj1绑定的作者
# 正向查询按外键字段,反向查询按表名小写# 一对一# 正向:author---关联字段在author表里--->authordetail 按字段# 反向:authordetail---关联字段在author表里--->author 按表名小写# 一对多# 正向:book---关联字段在book表里--->publish 按字段# 反向:publish---关联字段在book表里--->book 按表名小写_set.all() 因为一个出版社对应着多个图书# 多对多# 正向:book---关联字段在book表里--->author 按字段# 反向:author---关联字段在book表里--->book 按表名小写_set.all() 因为一个作者对应着多个图书
书籍与作者, 外键字段在书籍 book
作者与作者详情, 外键字段在作者 author
书籍与出版社外键字段在书籍 book
1.查询主键为1的书籍对应的出版社名称
# 先根据条件获取数据对象
book_obj = models.Book.objects.filter(pk=1).first()
# 再判断正反向的概念 由书查出版社 外键字段在书所在的表中 所以是正向查询
print(book_obj.publish.name)
2.查询主键为3的书籍对应的作者姓名
# 先根据条件获取数据对象
book_obj = models.Book.objects.filter(pk=3).first()
# 再判断正反向的概念 由书查作者 外键字段在书所在的表中 所以是正向查询 多对多关系
print(book_obj.authors)
print(book_obj.authors.all())
print(book_obj.authors.all().values('name'))
3.查询lufei的电话号码
# 根据作者查作者详情,外键字段在作者表,author和author_detail是一对一关系
author_obj = models.Author.objects.filter(name='lufei').first()
print(author_obj.author_detail.phone)
4.查询朵朵出版社出版过的书籍
# 根据出版社查询对应的书籍,外键字段在书籍
publish_obj = models.Publish.objects.filter(name='朵朵出版社').first()
print(publish_obj.book_set)
print(publish_obj.book_set.all())
print(publish_obj.book_set.all().values('title'))
5.查询lufei写过的书籍
# 根据作者查书籍,外键字段在书籍,多对多关系
author_obj = models.Author.objects.filter(name='lufei').first()
print(author_obj.book_set)
print(author_obj.book_set.all())
print(author_obj.book_set.all().values('title'))
6.查询电话号码是110的作者姓名
# 根据作者详情查作者,外键字段在作者author表,用表名小写
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
print(author_detail_obj.author)
print(author_detail_obj.author.name)
1.查询主键为1的书籍对应的出版社名称
# 根据书籍查出版社,正向查询,按照书籍表中外键字段publish查询,__name获取出版社名字res = models.Book.objects.filter(pk=1).values('publish__name')
2.查询主键为3的书籍对应的作者姓名
# 根据书籍查询作者,正向查询,按照书籍表中外键字段authors查询,__name获取作者姓名
res = models.Book.objects.filter(pk=3).values('authors__name')
3.查询lufei的电话号码
# 根据作者查作者详情,正向查询,按照作者表中外键字段author_detail查询,__phone获取电话
res = models.Author.objects.filter(name='lufei').values('author_detail__phone')
4.查询北方出版社出版过的书籍名称和价格
# 根据出版社查书籍,反向查询,按照被查表表名小写book查询,__XX获取相应的信息
res = models.Publish.objects.filter(name='北方出版社').values('book__title','book__price')
5.查询lufei写过的书籍
# 根据作者查书籍,反向查询,按照被查表表名小写book查询,__XX获取相应的信息
res = models.Author.objects.filter(name='lufei').values('book__title')
6.查询电话号码是110的作者姓名
# 根据作者详情查作者,反向查询,按照被查表表名小写author查询,__XX获取相应的信息
res = models.AuthorDetail.objects.filter(phone=110).values('author__name')
1.查询主键为1的书籍对应的出版社名称
# 根据书籍查出版社,正向查询,主键在书籍表中,从出版社查询为反向,按照正向的书籍表表名小写book查询,条件写在filter()括号中,values()括号中直接填写需要的键值'name'
res = models.Publish.objects.filter(book__pk=1).values('name')
2.查询主键为3的书籍对应的作者姓名
#根据书籍查作者,正向查询 主键在书籍表中,从作者查询为反向,按照正向的书籍表表名小写book查询,条件写在filter()括号中,values()括号中直接填写需要的键值'name'
res = models.Author.objects.filter(book__pk=3).values('name')
3.查询lufei的电话号码
# 根据作者查作者详情,正向查询,主键在作者表中,从电话号码查询为反向,按照正向的作者表表名小写author查询,条件写在filter()括号中,values()括号中直接填写需要的键值'phone'
res = models.AuthorDetail.objects.filter(author__name='lufei').values('phone')
4.查询北方出版社出版过的书籍名称和价格
# 根据出版社查询书籍,反向查询,主键在书籍表中,从书籍查询为正向,按照正向书籍表中外键名publish查询
res = models.Book.objects.filter(publish__name='北方出版社').values('title','price')
5.查询lufei写过的书籍
# 根据作者查询书籍,反向查询,主键在书籍表中,从书籍查询为正向,按照正向书籍表外键名authors查询
res = models.Book.objects.filter(authors__name='lufei').values('title')
6.查询电话号码是110的作者姓名
# 根据作者详情查作者,反向查询, 主键在作者表中,从作者查询为正向,按照正向作者表外键名author_detail查询
res = models.Author.objects.filter(author_detail__phone=110).values('name')
7.查询主键为3的书籍对应的作者的电话号码
# 1.从书籍表查询
# 书籍———>作者(正向按外键authors)————>详情(正向按外键author_detail)
res = models.Book.objects.filter(pk=3).values('authors__author_detail__phone')
# 2.从详情表查询
# 详情————>作者(反向按表名author)————>书籍(反向按表名book)
res = models.AuthorDetail.objects.filter(author__book__pk=3).values('phone')
# 3.从作者表查询
# 作者————>书籍(反向按表名book)
# 根据书籍主键获取到作者之后,直接到详情表中获取电话号码(正向按外键author_detail)
res = models.Author.objects.filter(book__pk=3).values('author_detail__phone')
五种聚合函数
1、aggregate()
from dels import Avg,Max,Min,Sum,Count # 导入聚合函数# 计算平均值
res = models.Book.objects.aggregate(Avg('price'))
# 指定名称
res = models.Book.objects.aggregate(avg_price=Avg('price')) res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Avg('price')) # 统计东方出版社出版的书籍的个数
res = models.Publish.objects.filter(name='东方出版社').aggregate(count_num=Count('book__id'))
objects.annotate()
values().annotate()
annotate().values()
filter().annotate()
annotate().filter()
#需要在测试文件中先导包
from dels import Max,Min,Count,Sum,Avg# 统计每个出版社出版的书的平均价格
res = models.Publish.objects.annotate(avg_price=Avg('book__price')).values('name','avg_price')# 统计每一本书的作者个数
res = models.Book.objects.annotate(count_num=Count('authors')).values('title','count_num')# 统计出每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')# 查询每个作者出的书的总价格
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')# 查询每个作者出的书的数量和总价格
res = models.Author.objects.annotate(total_num=Count('book__pk'),total_price=Sum('book__price'),).values('name','total_num','total_price')# 统计有多个作者的图书
# 第1步:先统计每本书的作者个数
author_num = models.Book.objects.annotate(authors_num=Count('authors__pk'))# 第2步:筛选出作者个数大于1的图书
res = models.Book.objects.annotate(author_num=Count('authors__pk')).filter(author_num__gt=1).values('title','author_num')"""按照字段分组"""
# 统计每个出版社所出的书的数量
res = models.Book.objects.values('publish_id').annotate(total_num=Count('pk')).values('publish__name','total_num')
还有F查询Q查询only、defer、select_related、prefetch_related,后续再了解
本文发布于:2024-01-29 11:51:59,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170650032515079.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |