django系列5—QuerySetAPI的增删改查操作
QuerySet API使⽤
QuerySet可以构造、过滤、切⽚、和⼤致的结果⽽不实际访问数据库。除⾮执⾏某些操作来评估查询集,否则实际上不会发⽣对数据库的查询活动。
(1) 基本属性
1. 迭代
QuerySet是可迭代的,并且在第⼀次对其迭代是会执⾏其数据库查询。如:
for e in Entry.objects.all():
print(e.headline)
2. 切⽚
可以使⽤python的数组切⽚语法对QuerySet集进⾏切⽚操作。
3. len
返回QuerySet列表的长度。
4. list
使⽤list()进⾏强制转化。entry_list = list(Entry.objects.all())
5. exists
判断结果集中是否存在⾄少⼀个结果。Entry.objects.all().exists()。
(2) 查询
1. filter
条件查,是⼀个结果集,多个条件时使⽤逗号(,)隔开。Entry.objects.filter(id=3,name=’张三’)。
2. exclude
筛选出与给定查参数不匹配的结果,是⼀个结果集,多个条件时使⽤逗号(,)隔开。lude(id=3,name=’张三’)。括号⾥⾯的参数属于and关系。当想使⽤or关系时要写多个exclude()。
3. annotate
表达式可以是简单值,也可以是对模型(或任何相关模型)上字段的引⽤,也可以是针对与对象中的对象相关的对象计算出的聚合表达式(平均值,总和等)
from dels import Count
q = Blog.objects.annotate(Count('entry'))
4. order_by
默认情况下可以在Meta给出的ordering排序元组进⾏排序,可以使⽤order_by()对ordering的⽅法进⾏覆盖,额外对查询结果进⾏排序。
如:
der_by('headline')
在字段名称前加负号(-)代表降序。
如果想要随机排序,可以使⽤"?",如下:
der_by('?')
**注意:**order_by(’?’)查询⽐较缓慢。
多次使⽤order_by时会使前边的排序规则失效。
5. reverse
使⽤reverse()可以翻转查询集元素的返回顺序。如:检索查询集中”最后”五个项⽬,可以执⾏以下操作:
der_by('headline').reverse()[:5]
6. distinct
消除重复的⾏。
der_by('pub_date').distinct('pub_date')
der_by('blog').distinct('blog')
7. values
返回QuerySet⽤作迭代器时返回的字典,⽽不是模型实例,这些词典中的每⼀个都代表对象,键对应于模型对象的属性名称。
Blog.objects.filter(name__startswith='Beatles')
#<QuerySet [<Blog: Beatles Blog>]>
Blog.objects.filter(name__startswith='Beatles').values()
#<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
values()⽅法可以采⽤可选的位置参数,如果指定字段,则每个字典将仅包含指定的字段的键/值,如果不指定字段,则每个字段将为数据库表忠中的每个字段包含⼀个键和值。如:
Blog.objects.values()
#<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
Blog.objects.values('id','name')
#<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>
values()⼦句中的聚合在同⼀values()⼦句中的其他参数之前应⽤。如果需要按另⼀个值分组,请将其添加到更早的values()⼦句中。
例如:
from dels import Count
Blog.objects.values('entry__authors',entries=Count('entry'))
#<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]
Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
#<QuerySet [{'entry__authors': 1, 'entries': 33}]>
8. value_list
类似于values,但是返回元组形式的数据,每个元组包含来⾃传递到values_list()中调⽤的相应字段或表达式的值。
Entry.objects.values_list('id','headline')
#<QuerySet [(1, 'First entry'), ...]>
from dels.functions import Lower
Entry.objects.values_list('id', Lower('headline'))
#<QuerySet [(1, 'first entry'), ...]>
如果仅传递单个字段,则也可以传递flat参数。如果flat为True,则表⽰返回的结果是单个值,⽽不是⼀个元组。
Entry.objects.values_list('id').order_by('id')
#<QuerySet[(1,), (2,), (3,), ...]>
Entry.objects.values_list('id', flat=**True**).order_by('id')
#<QuerySet [1, 2, 3, ...]>
可以通过named=True来获取结果named tuple()
Entry.objects.values_list('id','headline', named=**True**)
QuerySet [Row(id=1, headline='First entry'),...]>
如果不向values_list()中传递任何值,则按照声明的顺序返回模型中的所有字段,通常需要获取某个模型实例的特定字段值,因此需要values_list()配合get()使⽤。
Entry.objects.values_list('headline', flat=**True**).get(pk=1)
#'First entry'
9. dates
dates(field,kind,order =‘ASC’),返回结果是⼀个QuerySet,结果是⼀个datetime.date对象列表,该对象列表表⽰的内容中也定种类的所有可⽤⽇期QuerySet。
Field应该是DateField类型,kind可以为year,month,week,day。
1. “year”返回该字段的所有不同年份值的列表。
2. “month”返回该字段的所有不同年份/⽉份值的列表。
3. “week”返回该字段的所有不同年份/星期值的列表。所有⽇期均为星期⼀。
4. “day”返回该字段所有不同年/⽉/⽇值的列表。
10. none
创建⼀个空的查询集,该查询集不返回任何对象,并且在访问结果时不执⾏任何操作。
()
<QuerySet []>
from dels.query import EmptyQuerySet
isinstance((), EmptyQuerySet)
True
11. all
查询所有的数据。
12. raw
执⾏该查询会进⾏原始SQL查询。
for p in Person.objects.raw('SELECT * FROM myapp_person'):
print(p)#John SmithJane Jones
13. Q
and(&)连接符:
from dels import Q
以下为等价查询:
Model.objects.filter(x=1)& Model.objects.filter(y=2)
Model.objects.filter(x=1, y=2)
Model.objects.filter(Q(x=1)& Q(y=2))
等效于 SELECT ... WHERE x=1 AND y=2
14. or(|)
Model.objects.filter(x=1)| Model.objects.filter(y=2)
from dels import Q
Model.objects.filter(Q(x=1)| Q(y=2))
SQL等效项:
SELECT … WHERE x=1 OR y=2;
15. contains
模糊查询,区分⼤⼩写。
(headline__contains='Lennon')
16. icontains
模糊查询,不区分⼤⼩写。
(headline__icontains='Lennon')
17. in
查询在列表、元组或其他查询集中的数据,也可接收字符串。
Entry.objects.filter(id__in=[1,3,4])
Entry.objects.filter(headline__in='abc')
等价于:
SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c');
18. gt
⼤于。
Entry.objects.filter(id__gt=4)
19. gte
⼤于等于。
Entry.objects.filter(id__gte=4)
20. lt
⼩于。
Entry.objects.filter(id__lt=4)
21. lte
⼩于等于。
Entry.objects.filter(id__lte=4)
22. startswith
区分⼤⼩写,以…开头
Entry.objects.filter(headline__startswith='Lennon')
23. istartswidth
不区分⼤⼩写,以…开头
Entry.objects.filter(headline__istartswith='Lennon')
24. endswith
区分⼤⼩写,以…结束
Entry.objects.filter(headline__endswith='Lennon')
25. iendswith
区分⼤⼩写,以…结束
Entry.objects.filter(headline__iendswith='Lennon')
26. range
范围查询。
import datetime
start_date = datetime.date(2005,1,1)
end_date = datetime.date(2005,3,31)
Entry.objects.filter(pub_date__range=(start_date, end_date))
27. F
F允许Django在未实际链接数据的情况下,具有对数据库字段的值的引⽤。通常情况下会在更新数据时先从数据库⾥对原始数据取出后放在内存⾥,然后编辑某些属性进⾏提交。如:
order = (orderid='123456789')
order.amount +=1
提交更改是内存条吗order.save()
此时的SQL语句等效为:
UPDATE core_order SET ..., amount = 22 WHERE derid = '123456789'
# ...表⽰Order中的其他值,在这⾥会重新赋⼀遍值; 22表⽰为计算后的结果
当使⽤F()函数时:
from dels import F
dels import Order
order = (orderid='123456789')
order.amount = F('amount')-1
order.save()
此时SQL语句等价于:
UPDATE core_order SET ..., amount = amount + 1 WHERE derid = '123456789'
在使⽤此种⽅法跟新数据之后,需要重新加载数据来使数据库中的值与程序中的值对应:
order= (pk=order.pk)
#  或者使⽤更加简单的⽅法:
(3) 不适⽤于缓存的查询

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。