转一篇:文档笔记之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 ...
随机推荐
- 如何更改Json.NET的序列化规则
我想要使序列化出来的JSON都是小写,可以通过建立 LowercaseContractResolver:DefaultContractResolver 来实现, 创建Custom ContractRe ...
- jQuery Mobile 开发中常见的问题
目录 页面缩放显示问题 页面跳转后样式丢失js失效 跳转时重复调用pageinit方法的解决办法 如何调用loading效果 1页面缩放显示问题 问题描述: 页面似乎被缩小了,屏幕太宽了. 解决办 ...
- PowerDesigner中遍历物理模型中的所有表,检查表代码、字段代码
'***************************************************************************** '文件:CheckCode4SqlServ ...
- 从java到php
从大一开始就开始接触java这门语言.但是在这之前也接触了vb,c,asp等等开发语言,唯独java让人感觉严谨,清爽,各种数据之间的不拖泥带水.这才花费更多时间去研究他.但是学着学着,发现他体系的庞 ...
- Nginx的平滑重启和平滑升级
一,Nginx的平滑重启如果改变了Nginx的配置文件(nginx.conf),想重启Nginx,可以发送系统信号给Nginx主进程的方式来进行.在重启之前,要确认Nginx配置文件的语法是正确的. ...
- vs2010中安装ASP.NET AJAX Control Toolkit
方法一: 第一步 下载Ajax Control Toolkit 进入网址http://ajaxcontroltoolkit.codeplex.com/ 即可下载 第二步 解压下载下来的Ajax Con ...
- java之jar命令详解
1. JAR 文件包 JAR 文件就是 Java Archive File,顾名思意,它的应用是与 Java 息息相关的,是 Java 的一种文档格式.JAR 文件非常类似 ZIP 文件——准确的说, ...
- WPF-控件-层级控件-Menu-嵌套结构
<?xml version="1.0" encoding="utf-8" ?> <Data xmlns=""> &l ...
- winrar 压缩文件方法
问题描述: 我要一些大的文件进行压缩,看了网上有很多类拟的写法.但在我这都存在两个问题. 1.就是他们都是通过注册表找到rar的exe目录.我安装好winrar后,虽然注册表有,但那个目录一直报一个错 ...
- redis使用场景
Redis应用场景 Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作 ...