Django学习笔记:Models04 数据库查询

创建对象

①<表>.objects.create(<字段1>=’xxx’, <字段2>=’xxx’, ...)

②<变量> = <表>(<字段1>=’xxx’, <字段2>=’xxx’, ...)

  <变量>.save()

③<变量> = <表>()

  <变量>.<字段> = ’xxx’

  <变量>.save()

④<表>.objects.get_or_create(<字段1> = ’xxx’, <字段2> = ’xxx’, ...)

#返回一个元组(object, True/False),新建对象返回True,获取对象返回False。速度较慢。



查询对象

<表>.objects.all()

获取所有对象的集合。

<表>.objects.all()[:10]

切片获取前10条对象的集合,不支持负数切片。如果没有匹配到对象,会引发IndexError异常。

<表>.objects.all().reverse()[:3]

倒序获取后3条对象的集合。


<表>.objects.filter(<字段>=’xxx’)

获取所有匹配对象的集合形式,不存在则返回空集合,不报错。

获取单条数据用<表>.objects.filter(<字段>=’xxx’)[0]


<表>.objects.exclude(<字段>=’xxx’, <字段2>=’xxx’, ...)

获取除去匹配对象的所有对象集合。


<表>.objects.get(<字段>=’xxx’)

获取单条匹配的对象,如果没有匹配到,会引发DoesNotExist异常,如果匹配结果超过一个,

会引发MultipleObjectsReturned异常。慎用.get()。


字段查询的参数:用于filter(), exclude(),和get()

__iexact:完全匹配(忽略大小写)

__contains:包含匹配(__icontains忽略大小写)

__startswith:从开头位置匹配(__istartswith忽略大小写)

__endswith:从结尾位置匹配(__iendswith忽略大小写)

__gt:大于匹配(__gte大于等于)

__lt:小于匹配(__lte小于等于)

__in:列表内的匹配,可以=<列表>,也可以=<QuerySet对象>

__range:范围匹配,如date__range=(a, b),包含于a, b之中

__date:日期匹配(年,月,日),如=datetime.date(2010, 2, 2)

__year:年份匹配,如=2010

__quarter:季度匹配(1-4)

__month:月份匹配,如=12(1-12)

__week:周数匹配,如=52/53(1-52/53)

__week_day:周几的匹配,如=7,将周日设为1

__day:天数的匹配,如=31

__time:时间匹配,如=datetime.time(xxx)

__hour:小时匹配,如=23(0-23)

__minute:分钟匹配,如=59(0-59)

__second:秒数匹配,如=59(0-59)

__isnull:匹配空值,如=True/False

__regex:正则表达式匹配(__iregex忽略大小写),如=r’^/d’


<表>.objects.order_by(’<字段>’)

获取所有匹配的对象并升序排列,<-字段>是降序排列。


<表>.objects.filter(<字段1>=’xxx’).order_by(’<字段2>’)

获取匹配[字段1]的对象集合并按照[字段2]升序排列

<表>.objects.filter(<字段1>__contains=’xxx’).exclude(<字段2>=’xxxx’)

获取[字段1]包含xxx而排除[字段2]为xxxx的对象


get_object_or_404(<表>, <参数>)

获取对象,不存在则返回404错误


get_list_or_404(<表>, <参数>)

获取对象的列表,列表为空则返回404错误


查询是否有对象:<表>.objects.all().exists()

查询对象的数量:<表>.objects.count()



F对象

将模型内的一个字段与另一个字段比较,F对象支持加、减、乘、除、取模和幂运算操作。


from django.db.models import F

<表>.objects.filter(<字段1>__<查询参数>=F(‘<字段2>’) )

#用查询参数比较[字段1]和[字段2]


<表>.objects.filter(<字段1>__<查询参数>=F(‘<字段2>’) * 3)

#用查询参数比较[字段1]和3倍的[字段2]


<表>.objects.filter(<字段1>__<查询参数>=F(‘<字段2>’) + F(‘<字段3>’) )

#用查询参数比较[字段1]和[字段2、字段3的和]


对于date和date/time字段,还可以加减一个timedelta对象。

from datetime import timedelta

Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3) )

#发布3天后又进行修改的对象



Q对象

Q对象可封装查询集合,用于filter(),exclude(),get()等函数,Q对象要放在普通对象前面。

from django.db.models import Q

Q(<字段>__<查询参数>=’xxx’)


可用&(and)、|(or)、~(not)来组合Q对象,返回一个新的Q对象,如:

Poll.objects.filter(

Q(pub_date__year=2004) | ~Q(pub_date=date(2004, 7, 3)), question__startswith=’Who’)

#逗号分隔也表示逻辑“与”



复制对象

方法:创建一个实例对象并拷贝其所有的字段。

a = A(<字段1>=’xxx’, <字段2>=’xxx’, ...)

a.save()       #保存为pk=1的对象

a.pk = None   #创建一份新的copy

a.save()       #保存为另一个pk=2的对象

多对多、一对一对象的复制?



更新和删除对象

更新普通对象:

<对象>.update(<字段>=’xxx’)

可用F对象对模型中的字段本身进行全部更新,注意F对象不能跨表操作,如:

<表>.objects.all().update(<字段>=F(‘<字段>’) + 1)


删除对象:

<对象>.delete()

如果该对象是主对象,默认同时删除关联的外键对象



QuerySet的缓存

新建的QuerySet的缓存是空的,当QuerySet第一次被提交后,数据库执行实际查询操作,Django会把查询结果保存在缓存内,随后的对于该QuerySet的提交将重用这个缓存。缓存可以高效的利用查询结果,并降低数据库负载。下面两个例子:

print([e.headline for e in Entry.objects.all()])     #方法一,2次实际查询,加倍数据库的负载

print([e.pub_date for e in Entry.objects.all()])

queryset = Entry.objects.all()                 #方法二,1次实际查询

print([p.headline for p in queryset])             # 提交查询

print([p.pub_date for p in queryset])            # 重用缓存


对QuerySet建立缓存的操作:

[entry for entry in queryset]    #迭代

<表>.objacts.all()[:10:2]        #指定步长的切片(普通切片不查询)

bool(queryset)               #测试布尔值

entry in queryset

list(queryset)                  #列表转换


多对一关系创建缓存:

f = <外键表>.objects.select_related()

此时用f.<外键列>引用主对象,使用的就是缓存




ForeignKey的处理方法:

add(obj1, obj2, ...):添加指定的模型对象到关联的对象集中

create(**kwargs):创建一个新的对象,将它保存并放在关联的对象集中,返回新创建的对象

remove(obj1, obj2, ...):从关联的对象集中删除指定的模型对象

clear():清空关联的对象集

set(objs):重置关联的对象集

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容