创建对象
①<表>.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):重置关联的对象集