转一篇:文档笔记之Django QuerySet
这个放着,说不定以后作一些更深入的查询时,用得着的。
http://www.rapospectre.com/blog/7/
今天刚刚答完辩体完检就跑来更新博客了!!!
先补上第一篇:
一般情况下,我们在写Django项目需要操作QuerySet时一些常用的方法已经满足我们日常大多数需求,比如get、filter、exclude、delete神马的感觉就已经无所不能了,但随着项目但业务逻辑越来越复杂,这几个方法可能就不能很好但满足我们了,所以这时候,最好的办法是神马??对,读文档!这里的读文档不是有业务需求时去查文档,而是要为了阅读文档而阅读文档。以下也是作为我的文档阅读笔记,我记下了一些我以后可能会用到或者一些技巧性提升的东西,好,不废话,正文开始:
首先,我们假设有以下两个model:
class Entry(Model.models):
ip = models.CharField(max_length=20)
time = models.DateTimeField()
black = models.BooleanField(default=False)
class Blog(Model.models):
title = models.CharField(max_length=100)
content = models.CharField(max_length=500)
publish = models.BooleanField(default=False)
entry = models.ForeignField(Entry, relate_name='entrys')
1、annotate(args, *kwargs)
为queryset增加注解,神马是注解?就是你读出queryset可能会需要一些额外数据要添加进去的时候,你就可以用这个东东咯,使用方法看代码:
>>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog
>>> q[0].name
'Blogasaurus'
# The number of entries on the first blog
>>> q[0].entry__count
42
Blog model 类本身并没有定义 entry__count 属性,但可以使用注解函式的关系字参数,从而改变注解的命名:
>>> q = Blog.objects.annotate(number_of_entries=Count('entry'))
# The number of entries on the first blog, using the name provided
>>> q[0].number_of_entries
42
2、aggregate(args, *kwargs) 这个参数有点像annotate的反义,annotate返回的是一个包含注解值的queryset,而aggregate则单独返回注解值,返回类型是一个dict,当然,这种方式在文档中叫做聚合查询,具体使用如下:
>>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16}
通过在 aggregate 指定关键字参数,你可以控制返回的聚合名称:
>>> q = Blog.objects.aggregate(number_of_entries=Count('entry'))
{'number_of_entries': 16}
3、defer(*fields) 延后读取字段。啥意思?我读文档时就这感觉。。后来发现是酱紫滴,一个复杂滴model可能你从数据库中读出后根本不需要某些字段,读了又浪费时间浪费空间,怎么办?对!用defer,延后读取,你可以在defer中指定一个或多个字段,也可用链式方法使用defer,它返回对依然是个完整对queryset但其中defer指定但字段并没有真但从数据库读出来,只有当你访问这些延后字段时django才会从数据库读取这些数据,感觉在数据量变大后用这个方法很nice,具体用法如下:
Blog.objects.defer("content").filter(publish=True).defer("title")
不过要注意的是,不能用defer过的字段进行order_by操作,这样做木有作用滴,如果需要清楚defer,只要加个defer(None)就ok啦。
你还阔以defer model中的外键,但是你需要提使用 select_related() 载入关联 model,具体用法:
Blog.objects.select_related().defer("entry__ip", "entry__time")
4、only(*fields) 我想你已经猜到了,一定是defer相反的咯,是啊是啊,没错。only会立即查询指定的字段,但是要注意了,这有坑,only只返回指定的字段,其他木有指定的默认就给defer了哟,所以以下写法是等价滴:
Entry.objects.only('ip')
Entry.objects.defer('time', 'black')
当你使用链式方法调用only时只有最后一个only内的参数会立即返回,其他参数都会被defer,注意这里only的覆盖性~
5、create(**kwargs) 创建并保存对象。一般我们要新建一个model对象时直接使用他的构造函数或者使用.语法赋值,最后调用.save()方法保存。那么在我们已经知道新建这个对象所有必须数据的情况下,其实用create会更快捷,代码看着更干净,起使用方法与构造方法类似,只是不需要调用.save()啦, 例子如下:
p = Entry.objects.create(ip='127.0.0.1', time=<a datetime type object>, black=False)
6、get_or_create(kwargs) 和 update_or_create(kwargs)
嗯,看看就知道这个是create的升级版,没错,他们俩一个是在查无此数据后新建一个是更新不存在数据时新建,具体用法同create,get_or_create等效如下过程:
try:
obj = Blog.objects.get(title='test', content='test')
except Blog.DoesNotExist:
obj = Blog(title='test', content='test')
obj.save()
注意这两个方法的返回值,他们返回两个东东:
created, obj = get_or_create(**kwargs)
其中created是个bool值,当此方法生成了一个新的model object,此值为True,反之为False,obj则是生成的object或者查到的object实例。
7、latest(field_name=None) 和 earliest(field_name=None) 分别返回指定字段的最新数据与最早数据。
8、first() 和 last() 分别返回queryset的第一项与最后一项,具体用法如下:
p = Blog.objects.order_by('title').first()
等同于:
try:
p = Blog.objects.order_by('title')[0]
except IndexError:
p = None
9、update(**kwargs) 用于更新一组数据,但要注意,它不能更新外键, 不能更新切片过的queryset以及不能再被切片的set,用法如下:
Entry.objects.filter(black=False).update(ip='0.0.0.0')
10、delete() 有人肯定要说了,博主你再逗我,这个方法抬头不见低头见,还用你说?!是啊是啊,删除普通数据的时候当然木有什么,但是如果删除外健关系很复杂的object时有木有想过细节?是不是细思极恐 啊#_# 比如,以我们开头的model为例,我删了一个entry实例,那么与它有外健关联的blog实例会怎样?一同被删了?还是保留?保留的话那他对应的entry外健是神马?WTF! 嗯,实话告诉你,默认情况下调用delete()是会删除所有有关的外键对象的(是不是突然感觉自己之前代码里有坑了)所以我们需要详细说说这个方法,如何做才能让他不删除对应的外键或者说按照我们想象的方式进行删除呢?
答案在这里:
django.models 的on_delete参数,此参数有以下几个可选值:
- CASCADE:这就是delete()的默认选项,也就是关联删除
- PROTECT:如果删除的model obj含有外键则引起 ProtectedError
- SET_NULL:就是把外键置空咯,当然前提是你得设置外键的
null=True - SET_DEFAULT:就是把外键设为默认咯,当然前提是你得设置外键的
default=xxx - SET():SET内应是一个函数,用来返回一个外键实例,用法如下:
def get_sentinel_user(): return get_user_model().objects.get_or_create(username='deleted')[0] class MyModel(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user))
11、fields lookups 强大滴django fields lookups,具体可选参数有:
iexact icontains in istartwith gt gte lt lte endwith iendwith range year month day week_day hour minute second insole (ex: search) iregex
其中,首字母带“i”的意思就是不分大小写,如果需要大小写敏感就把“i”去掉啦~其他参数大体从字面意思就知道啦,改天补上详细的�例子。
12、Avg、Count、Sum、Max、Min、StdDev、Variance 这些方法就是求数据的相应结果咯,比如avg就是平均值啦,嗯,基本都看得懂,除了后两个,一个是方差,一个是标准差,具体用法其实前文里有,我还是放一下:
q = Blog.objects.annotate(Count('entry'))
13、强大的Q查询与F查询: 嗯,这一部分先留着,总之告诉你很腻害就是了,可以做很复杂的查询,先放个例子:
q = Blog.objects.filter(Q(title='test')|Q(content='hahaha'))
这是一个或查询,满足其中一个条件的数据会被返回。
好,我们下期再见(对,博主懒病犯了,反正也没人看2333333)
转一篇:文档笔记之Django QuerySet的更多相关文章
- Django-RQ首页、文档和下载 - Django 和 RQ 集成 - 开源中国社区
Django-RQ首页.文档和下载 - Django 和 RQ 集成 - 开源中国社区 Django-RQ 项目实现了 Django 框架和 RQ 消息队列之间的集成.
- ABP文档笔记系列
ABP文档笔记 - 模块系统 及 配置中心 ABP文档笔记 - 事件BUS ABP文档笔记 - 数据过滤 ABP文档笔记 - 规约 ABP文档笔记 - 配置.设置.版本.功能.权限 ABP文档笔记 - ...
- 深入理解DOM节点类型第七篇——文档节点DOCUMENT
× 目录 [1]特征 [2]快捷访问 [3]文档写入 前面的话 文档节点document,隶属于表示浏览器的window对象,它表示网页页面,又被称为根节点.本文将详细介绍文档节点document的内 ...
- 深入理解DOM节点类型第四篇——文档片段节点DocumentFragment
× 目录 [1]特征 [2]作用 前面的话 在所有节点类型中,只有文档片段节点DocumentFragment在文档中没有对应的标记.DOM规定文档片段(document fragment)是一种“轻 ...
- ABP文档笔记 - 通知
基础概念 两种通知发送方式 直接发送给目标用户 用户订阅某类通知,发送这类通知时直接分发给它们. 两种通知类型 一般通知:任意的通知类型 "如果一个用户发送一个好友请求,那么通知我" ...
- ABP文档笔记 - 数据过滤
预定义的过滤 ISoftDelete 软删除过滤用来在查询数据库时,自动过滤(从结果中抽取)已删除的实体.如果一个实体可以被软删除,它必须实现ISoftDelete接口,该接口只定义了一个IsDele ...
- ABP文档笔记 - 事件BUS
文档: ABP框架 - 领域事件(EventBus) EventBus & Domain Events ABP源码分析二十五:EventBus EventBus(事件总线) EventBus是 ...
- asp.net mvc5中使用Swagger 自动生成WebApi文档笔记
Swagger可以自动生成Api说明文档,并内置在线测试,通过NSwagStudio还可以自动生成Api客户端调用代码,以下为具体实现步骤 1.写一个简单的WebApi并加上注释 public cla ...
- elasticsearch 第五篇(文档操作接口)
INDEX API 示例: 1 2 3 4 5 PUT /test/user/1 { "name": "silence", "age": 2 ...
随机推荐
- 必须知道的.NET FrameWork
这部分内容呢,对普通开发者来说,意义不是特别大.但是作为一个有情怀的开发者,应该追根溯源,懂一些自己用的工具, 的粗浅知识.并且这部分内容可以用来个HR吹嘘一下自己的情怀.基本就是这样. .NET生成 ...
- 实验三——SDRAM
一.运行环境 开发板:jz2440 系统: ubuntu12.04 编译器:arm-linux-gcc 二.特殊寄存器 sdram的操作无需按照时序图来设置,只要设置好相关的13个寄存器,arm处理 ...
- 把url后面的.html去掉
$url = "http://haichuang1997.bmlink.com/supply/dc_355472.html";echo rtrim($url, '.html');
- NSS_04 extjs中grid接收datetime类型参数列
今天在做用户列表时发现, asp.net mvc3的控制器在返回JsonResult结果时, 会把对象内的DateTime类型成员,解析为类似于\/Date(1238606590509)\/的格式 , ...
- PHP运行方式对比
文章内容来自以下站点http://www.cnblogs.com/xia520pi/p/3914964.html 关于PHP目前比较常见的五大运行模式: 1.CGI(通用网关接口 / Common G ...
- 【Sql Server】使用触发器把一个表中满足条件的数据部分字段插入到另一个表中
create trigger 触发器名称 on 对哪个表起作用 after insert,update as return set nocount on begin transaction; inse ...
- Redis源码研究--跳表
-------------6月29日-------------------- 简单看了下跳表这一数据结构,理解起来很真实,效率可以和红黑树相比.我就喜欢这样的. typedef struct zski ...
- Mysql 正则获取字段的交集【转】
问题描述 比如table1中有两条记录 name no a 2,9 b 8,10 然后有一串字符串,是0,1,2,3,4 然后通过一条sql,找出no为2,9的记录来``` 因为字符串中有 ...
- delphi图形图像开发相关
①delphi的图形处理(doc) http://wenku.baidu.com/view/519df09951e79b89680226ee.html ②delphi的图形图像处理(ppt) http ...
- 小课堂Week9 例外处理设计的逆袭Part2
小课堂Week9 例外处理设计的逆袭Part2 今天继续阅读<例外处理设计的逆袭>这本书,我们先看两个案例: 案例1 问:如果要设计一个依据学号到数据库中查询学生资料的函数,当找不到符合条 ...