Django模型基础二: 常用查询及表关系的实现

本文详细介绍了Django的ORM操作,包括如何使用QuerySet进行数据筛选、排序、聚合及分组查询,同时还涵盖了模型字段类型和表关系实现等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常用查询

每一个django模型类,都有一个默认的管理器,objects
在这里插入图片描述
QuerySet表示数据库中对象的列表。它可以有0到多个过滤器。过滤器通过给定参数,缩小查询范围(filter)

QuerySet等同于select语句,过滤器是一个限制子句,比如where,比如 limit。

查询方法
在这里插入图片描述

  • all() 获取所有

Student.objects.all()   # 返回的是queryset 

  • 获取第一个条

Student.objects.first()   # 返回的是对象

  • 获取最后一条

Student.objects.last()  # 返回的是对象

  • get(**kwargs)根据给定的条件获取一个对象,如果符合多个,或没有就会报错

  • fitler(**kwargs)过滤,根据参数提供的条件,获取一个过滤器后的QuerySet,多个条件等同于 select子句 使用and连接,关键字参数的形参必须是模型中的字段名。


In [13]: Student.objects.filter(name='小华').filter(age='19')                           
Out[13]: <QuerySet [<Student: 小华>]>


在这里插入图片描述

  • exclude(**kwargs), 用法和filter一样,作用相反,它是排除。

In [14]: Student.objects.exclude(age='18')                                              
Out[14]: <QuerySet [<Student: 小华>]>

在这里插入图片描述

  • order_by(*fields),根据给定的字段排序。

In [22]: Student.objects.all().order_by('age')                                          
Out[22]: <QuerySet [<Student: 小红>, <Student: 小华>, <Student: pet>]>

In [23]: res = Student.objects.all()                                                    

In [24]: res.order_by('age')                                                            
Out[24]: <QuerySet [<Student: 小红>, <Student: 小华>, <Student: pet>]>

In [25]: print(res.order_by('age').query)                                               
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, 
`teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, 
`teacher_student`.`time` FROM `teacher_student` ORDER BY `teacher_student`.`age` ASC


在这里插入图片描述在这里插入图片描述
多条件:有先后顺序

在这里插入图片描述
倒序


In [28]: print(res.order_by('-age','name').query)     #  默认asc,-age 代表反向排序

在这里插入图片描述

  • 切片 使用列表的切片语法操作query,除了不能用负索引,其他的都可以,它等价于LIMIT与OFFSET子句
    在这里插入图片描述

1.数据库数据计算是从0开始的

2.offset X是跳过X个数据,limit Y是选取Y个数据

3.limit X,Y 中X表示跳过X个数据,读取Y个数据
在这里插入图片描述
在这里插入图片描述

  • values(*fields)返回queryset, 这个queryset返回的是一个字典列表。参数fields指定了select中我们想要限制查询的字段。返回的字典列表中,只会包含我们指定的字段。如果不指定,包含所有字段。

In [38]: res = Student.objects.values('age')                                                               

In [39]: res                                                                                               
Out[39]: <QuerySet [{'age': 19}, {'age': 16}, {'age': 22}]>

在这里插入图片描述在这里插入图片描述

  • only(*fields)返回一个queryset,跟values一样,区别在于这个queryset是对象列表,only一定包含主键。

In [44]: s = Student.objects.only('name')                                  

In [45]: s                                                                 
Out[45]: <QuerySet [<Student: 小华>, <Student: 小红>, <Student: pet>]>

In [46]: print(s.query)                                                    
SELECT `teacher_student`.`id`, `teacher_student`.`name` FROM `teacher_student`

在这里插入图片描述

  • defer(fields) 用法与only相反(除了fields这个字段不要之外,其他的都要)

In [47]: s = Student.objects.defer('name')                                       

In [48]: s                                                                       
Out[48]: <QuerySet [<Student: 小华>, <Student: 小红>, <Student: pet>]>

In [49]: print(s.query)                                                          
SELECT `teacher_student`.`id`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`time` FROM `teacher_student`


在这里插入图片描述

  • 多条件OR连接,需要实现OR条件,我们要使用Q对象。



In [50]: from django.db.models import Q                                            

In [51]: res = Student.objects.filter(Q(age=16)|Q(age=19))                         

In [52]: res                                                                       
Out[52]: <QuerySet [<Student: 小华>, <Student: 小红>]>

In [53]: print(res.query)                                                          
SELECT `teacher_student`.`id`, `teacher_student`.`name`, `teacher_student`.`age`, `teacher_student`.`sex`, `teacher_student`.`qq`, `teacher_student`.`phone`, `teacher_student`.`time` FROM `teacher_student` WHERE (`teacher_student`.`age` = 16 OR `teacher_student`.`age` = 19)



在这里插入图片描述在这里插入图片描述
查询条件

语法都是field__conditon 是 两个下划线

在这里插入图片描述

  • exact (精确匹配,相当于等于)在这里插入图片描述

  • iexact ( 忽略大小写)在这里插入图片描述

  • contains (包含)在这里插入图片描述在这里插入图片描述

  • icontains (忽略大小写)在这里插入图片描述

  • in (是否包含在范围内)在这里插入图片描述

  • gt (大于)在这里插入图片描述

  • gte (大于等于)

  • lt (小于)

  • lte (小于等于)

  • startswith (以什么什么开始)在这里插入图片描述

  • istartswith (忽略大小写)

  • endswith (以什么什么结尾)在这里插入图片描述

  • iendswith (忽略大小写)

  • range ( 范围区间)在这里插入图片描述

  • isnull (判断是否为空)在这里插入图片描述

  • count() (统计数量 (返回queryset的长度))在这里插入图片描述

聚合函数

  • Avg 平均值

    # 计算同学们的年龄平均值
In [65]: from django.db.models import Avg                                                              

In [66]: res = Student.objects.aggregate(agg=Avg('age'))                                               

In [67]: res                                                                                           
Out[67]: {'agg': 19.0}

在这里插入图片描述

  • Max 最大值
		# 找到最大的年龄
		
In [70]: from django.db.models import Avg, Max, Min, Sum                                               

In [71]: res = Student.objects.aggregate(agg=Max('age'))                                               

In [72]: res                                                                                           
Out[72]: {'agg': 22}

在这里插入图片描述

  • Min 最小值
	# 找到最小的年龄
In [73]: res = Student.objects.aggregate(agg=Min('age'))                                               

In [74]: res                                                                                           
Out[74]: {'agg': 16}


在这里插入图片描述

  • Sum求和
 		# 计算同学们的年龄和
 		
In [75]: res = Student.objects.aggregate(agg=Sum('age'))                                               

In [76]: res                                                                                           
Out[76]: {'agg': 57}

在这里插入图片描述

分组聚合查询

聚合,分组需要结合 values , annotate 和聚合方法

看下面的案例

语法:

values(‘分组字段’).annotate(别名=聚合函数(‘字段’)).filter(聚合字段别名条件).values(‘取分组字段’, ‘取聚合字段别名’)

规则

1.values(…).annotate(…)为分组组合,values控制分组字段,annotate控制聚合字段

2.values可按多个字段分组values(‘分组字段1’, …, ‘分组字段n’),??如果省略代表按操作表的主键分组

3.可以同时对多个字段进行聚合处理annotate(别名1=聚合函数1(‘字段1’), …, 别名n=聚合函数n(‘字段n’))

4.分组后的的filter代表having判断,只对聚合字段进行条件判断,可以省略(对非聚合字段或分组字段进行条件判断代表where判断)

5.取字段值values(…)省略默认取所有分组字段与聚合字段,也可以自主取个别分组字段及聚合字段(取字段的values中出现了非分组或非聚合字段,该字段自动成为分组字段)


  # 查询男生女生分别有多少人
  
In [81]: from django.db.models import Avg, Max, Min, Sum, Count                                        

In [82]: res = Student.objects.values('sex').annotate(Count('sex'))                                    

In [83]: res                                                                                           
Out[83]: <QuerySet [{'sex': 0, 'sex__count': 1}, {'sex': 1, 'sex__count': 2}]>

在这里插入图片描述

常用模型字段类型

官方文档https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-types
在这里插入图片描述在这里插入图片描述在这里插入图片描述

表关系实现

django 中,模型通过特殊的字段进行关系连接

在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 一对一在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 一对多在这里插入图片描述
    在这里插入图片描述

  • 多对多

在这里插入图片描述在这里插入图片描述在这里插入图片描述

注:在多对多表关系中,如果我们有而外字段的情况下需要手动创建第三张表。

在这里插入图片描述在这里插入图片描述在这里插入图片描述
所有我们需要手动指定第三张表在这里插入图片描述在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值