django QuerySet Api介绍-----返回QuerySets的

本文详细介绍了Django的QuerySet API,包括filter、exclude、annotate、order_by、reverse、values、distinct、values_list、dates、datetimes、select_related、prefetch_related、extra、defer、only、using、select_for_update和raw等方法的使用和注意事项,旨在帮助开发者更好地理解和优化Django查询操作。

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

1、filter(**kwargs)
多个参数间是AND关系

2、exclude(**kwargs)
多个参数间是AND关系,查找NOT不匹配的记录

3、annotate(*args, **kwargs)
对QuerySets中每条记录增加批注,批注参数列表中每个表达式计算的结果。将每个结果对应批注到每条记录上。args使用缺省别名,kwargs使用关键字作为别名

4、order_by(*fields)
a、QuerySets通常按照Meta中的ordering选项排序,也可以通过使用order_by方法定制单个QuerySets的返回排序。‘-field’为降序,缺省为升序,‘?’为乱序(此种情况性能低) b
b、可以使用关联模型的某个字段“关联模型__field”排序
c、直接使用关联模型,则排序使用关联模型中Meta中的ordering排序,如果没有,则使用默认排序,即关联模型的primary key排序。
d、也可以按照query expressions排序,通过调用query expressions的asc、desc方法
e、 如果使用一对多的反向关系,或者多对多关系的关联对象排序,QuerySets中会多出重复查询记录(原因:order_by中每个field,都会出现在select的column中,但是不返回,因此从返回结果看产生了重复的查询结果),注意!!!!。使用distinc(),可以消除重复记录,但需要小写使用 f、无法定义排序是否大小写敏感,django会依照数据库对字符串排序的方式进行排序。通过调用Lower可以达到大小写一致的排序目的:Entry.objects.order_by(Lower(‘headline’).desc())
g、如果不希望进行任何排序包括缺省排序,无参调用order_by()
h、每次order_by()都会清空前一次order_by()的排序
i、会造成性能损耗
j、如果查询未定义排序,则以未知排序返回QuerySets
k、唯一确定一记录的项集合排序,则总是返回顺序的结果

5、reverse()
a、逆序查询结果,再次调用则恢复原始排序。
b、如果查询无排序(order_by调用或者缺省排序),reverse()不起作用

6、values(*fields, **expressions)
使用场合同values_list, 用于优化,仅查询特定几个项,不用创建模型实例 a、返回的QuerySets中为字典而不是模型实例
b、*fields参数定义SELECT列项,仅返回定义的项,可选参数,缺省为全返回
c、**expressions用于传给annotate使用,
d、聚合计算先于其他参数计算,如果希望分组或者后计算,则需将聚合计算反正后一个values()调用中,或者annotate中
e、使用distinct去除重复时,需要注意ordering可能影响结果
f、extra调用在values前面,则必须将extra中的参数添加至values中;extra调用在values后面,则忽略
g、only和defer在values后面调用,无意义,会触发NotImplementedError h、可以仅查询需要的特定几个项,这样可以提高效率
i、filter和order_by放在values前后都一样,一般将SQL执行语句类调用放前,影响输出结果类调用放后面
j、可以逆向输出关联模型中的数据项:“关联模型名小写__field”,其中可以嵌套关联模型:比如:Entry的外键为Blog,多对多键为Author。查询Blog通过Entry关联到的Author的名字,可以这样写:Blog.objects.values(“name”, “entry__authors__name”)。当然这种情况下,返回的结果会非常多

7、distinct(*fields)
a、对QuerySets进行计算,有可能产生重复项,如“4、order_by”,此种情况下,可以使用distinct
b、注意依靠关联关系排序时,会使用关联模型的Meta中定义的缺省排序进行,因此,如果意图使用关联关系的primary key排序,需要直接指定出来

8、values_list(*fields, flat=False, named=False)
使用场合同values, 用于优化,仅查询特定几个项,不用创建模型实例
a、同values,只是返回tuple
b、仅有一个fields,可设置flat为True,此时仅返回Python原始值
c、设置named=True(此参数django2.0增加),返回的是namedtuple
d、对应关联对象,如果无关联值,则设置为None

9、dates(field, kind, order=’ASC’)
返回的QuerySets为datetime.date对象的列表,
a、field为模型中类型为DateField的项
b、kind(返回的值会截取为对应的kind,如何截取,见例子中的红色)可取:year、month、day,
c、order返回结果排序:ASC、DESC。
例子:>

Entry.objects.dates(‘pub_date’, ‘year’)
[datetime.date(2005, 1, 1)]

Entry.objects.dates(‘pub_date’, ‘month’)
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]

Entry.objects.dates(‘pub_date’, ‘day’)
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]

10、datetimes(field_name, kind, order=’ASC’, tzinfo=None)
返回的QuerySets为datetime.datetime的对象列表,field_name为模型中为DateTimeField的项,kind(也会按类型截取,同上面9):year、month、day、hour、minute、second,输出排序order:ASC、DESC, tzinfo:如果UST_TZ设为False,则此参数忽略

11、select_related(*fields)
a.select_related主要针一对一和多对一关系进行优化。
b.select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。
c.可以通过可变长参数指定需要select_related的字段名。也可以通过使用双下划线“__”连接字段名来实现指定的递归查询。没有指定的字段不会缓存,没有指定的深度不会缓存,如果要访问的话Django会再次进行SQL查询。
d.也可以通过depth参数指定递归的深度,Django会自动缓存指定深度内所有的字段。如果要访问指定深度外的字段,Django会再次进行SQL查询。
e.也接受无参数的调用,Django会尽可能深的递归查询所有的字段。但注意有Django递归的限制和性能的浪费。
f.Django >= 1.7,链式调用的select_related相当于使用可变长参数。Django < 1.7,链式调用会导致前边的select_related失效,只保留最后一个。

12、prefetch_related(*lookups)
将关联表数据,分别批量查询出来,在Python层面完成join,不同于select_related在database查询时进行join,可以支持多对多、多对一关系。 a、同样支持GenericRelation、GenericForeignKey
b、链式调用,仅仅是累积lookups
c、参数为None,会情空QuerySets中的prefetch缓存
d、多对一的关系,prefetch的结果,可以供其他模型实例使用
e、prefetch_related使用IN,如果IN后数据巨大,则可能在解析或者执行SQL语句时存在性能风险
f、与iterator()一起使用是,会忽略prefetch_related
g、使用入参Prefetch来控制prefetch操作,Prefetch仅包含字符串时等价于prefetch_related入参“字符串lookup”,两者可以混用。Prefetch可以设置querysets,可以设置to_attr。
h、lookups的顺序不可随意
i、需要定制querysets场合时,prefetch-related要替代select_related。在Many-to-one和One-to-One场合,使用select_related会更高效

13、extra在django方法无法表达WHERE语句时,使用extra调用注入原始SQL语句至产生的SQL语句中。此方法不推荐使用,未来要废弃

14、defer(*fields)
a、延迟加载某些fields,直到访问时再查询,入参为None时清空原因deferred设置。
b、primary key设置defer无效,relate fields设置defer无效,会忽略
c、如果在queryset加载阶段可以肯定不需要哪些项,可以采用设置Meta managed=True的方式来代替defer,这样会更高效。如果unmanaged model中很多字段都需要复制,则可以设置abstract models

15、only(*fields)
只加载某些fields,需要注意的点通14

16、using(alias)
有多个databases时,指定在哪个数据库查询。alias为在DATABASES中指定的节点名

17、select_for_update(nowait=False,skip_locked=False,of=())
a、在支持SELECT … FOR UPDATE的数据库上,执行此操作,产生的querysets会对读取记录加锁,直到事务结束
b、设置nowait=True,则如果加锁,直接返回
c、设置skip_locked=True,则如果加锁,跳过加锁记录
e、of,设置表级别的加锁,可将select_related中的lookups,设置在of中,设置primary模型使用self。
f、如果related对象可以为null,会报错,
g、当前Postgresql、Oracle、mysql支持此操作。但是mysql不支持nowait、skip_locked、of,会报错
h、nowait和skip_locked不可以同时使用,会报错
i、如果数据库不支持此项操作,则完全忽略此调用 j
、如果处于autocommit模式,调用此函数会报错,防止数据库崩溃
k、单元测试时需要使用TransactionTestCase,而非TestCase

18、raw(raw_query, params=None, translations=None)
执行原始SQL语句

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值