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:列表内的匹配,可以=<列表>,也可以=

__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):重置关联的对象集

你可能感兴趣的:(Django学习笔记:Models04 数据库查询)