这个放着,说不定以后作一些更深入的查询时,用得着的。

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的升级版,没错,他们俩一个是在查无此数据后新建一个是更新不存在数据时新建,具体用法同createget_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的更多相关文章

  1. Django-RQ首页、文档和下载 - Django 和 RQ 集成 - 开源中国社区

    Django-RQ首页.文档和下载 - Django 和 RQ 集成 - 开源中国社区 Django-RQ 项目实现了 Django 框架和 RQ 消息队列之间的集成.

  2. ABP文档笔记系列

    ABP文档笔记 - 模块系统 及 配置中心 ABP文档笔记 - 事件BUS ABP文档笔记 - 数据过滤 ABP文档笔记 - 规约 ABP文档笔记 - 配置.设置.版本.功能.权限 ABP文档笔记 - ...

  3. 深入理解DOM节点类型第七篇——文档节点DOCUMENT

    × 目录 [1]特征 [2]快捷访问 [3]文档写入 前面的话 文档节点document,隶属于表示浏览器的window对象,它表示网页页面,又被称为根节点.本文将详细介绍文档节点document的内 ...

  4. 深入理解DOM节点类型第四篇——文档片段节点DocumentFragment

    × 目录 [1]特征 [2]作用 前面的话 在所有节点类型中,只有文档片段节点DocumentFragment在文档中没有对应的标记.DOM规定文档片段(document fragment)是一种“轻 ...

  5. ABP文档笔记 - 通知

    基础概念 两种通知发送方式 直接发送给目标用户 用户订阅某类通知,发送这类通知时直接分发给它们. 两种通知类型 一般通知:任意的通知类型 "如果一个用户发送一个好友请求,那么通知我" ...

  6. ABP文档笔记 - 数据过滤

    预定义的过滤 ISoftDelete 软删除过滤用来在查询数据库时,自动过滤(从结果中抽取)已删除的实体.如果一个实体可以被软删除,它必须实现ISoftDelete接口,该接口只定义了一个IsDele ...

  7. ABP文档笔记 - 事件BUS

    文档: ABP框架 - 领域事件(EventBus) EventBus & Domain Events ABP源码分析二十五:EventBus EventBus(事件总线) EventBus是 ...

  8. asp.net mvc5中使用Swagger 自动生成WebApi文档笔记

    Swagger可以自动生成Api说明文档,并内置在线测试,通过NSwagStudio还可以自动生成Api客户端调用代码,以下为具体实现步骤 1.写一个简单的WebApi并加上注释 public cla ...

  9. elasticsearch 第五篇(文档操作接口)

    INDEX API 示例: 1 2 3 4 5 PUT /test/user/1 { "name": "silence", "age": 2 ...

随机推荐

  1. 【风马一族_git_github】git的工作流程

    git有三个区域(如图): 基本信息设置 1)设置用户名   git config --global user.name  "帐号名" 2)设置用户名邮箱  git config ...

  2. 用canvas 绘制的饼状统计图、柱状统计图、折线统计图

    canvas 绘制的饼状统计图 canvas 绘制的柱状统计图 canvas 绘制的折线统计图

  3. winform INI文件操作辅助类

    using System;using System.Runtime.InteropServices;using System.Text; namespace connectCMCC.Utils{ // ...

  4. 初测WIN10

    WIN10已经发布,通过百度直通车把WIN7升级成了WIN10,改变较大,不太习惯,用着不是很顺手. 吐槽几个问题 1.微软的Visual Studio 2015 Community版本,宣布是免费的 ...

  5. Reveal 配置与使用

    http://www.th7.cn/Program/IOS/201608/939231.shtml http://www.jianshu.com/p/abac941c2e8e 这个比较好.http:/ ...

  6. 删除 mysql (rpm)

    http://blog.csdn.net/love__coder/article/details/6894566 a)查看系统中是否以rpm包安装的mysql [root@linux ~]# rpm  ...

  7. LANMP 如何禁止访问 .htaccess 文件

    很多朋友问我,为什么他已经在 Apache 规则里面加了禁止别人直接下载 .htaccess 文件,为什么还是可以下载? 其实这个很简单,因为 .htaccess 在 LANMP 环境下,当他作为文件 ...

  8. php读取html并截取字符串

    一般php采集代码能用的到,这里只是简单的实现代码. <?php $title='脚本学堂'; $hello='jbxue.com!'; $file=file_get_contents('htt ...

  9. javascript和jquery 获取触发事件的元素

    一个很简单的问题,却因为大意,经常忘了处理,导致程序运行出错. <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  10. C# sogou地图API应用总结(二)

    在地图上添加自己想要的功能模块 具体代码如下 var map; window.onload = function () { var myOptions = { mapControl: false, / ...