QuerySets
Internally, a QuerySet can be constructed, filtered, sliced.
只有当进行取值操作时候,才会触发数据库操作。
触发数据库操作的方式
- Iteration
- Slicing,例如 Entry.objects.all()[:5]
- Pickling/Caching
- repr()
- len()
- list(),例如 list(Entry.objects.all())
- bool()
参考链接:https://docs.djangoproject.com/en/1.11/ref/models/querysets/#when-querysets-are-evaluated
Iteration
1 | for e in Entry.objects.all(): |
Limiting
返回5个对象 (等价 LIMIT 5)
1 | Entry.objects.all()[:5] |
分页返回对象 (等价 OFFSET 5 LIMIT 5)
1 | Entry.objects.all()[5:10] |
生成List
1 | entry_list = list(Entry.objects.all()) |
bool
1 | if Entry.objects.filter(headline="Test"): |
此时会触发数据库查询操作,如果查询结果中至少有一个对象,则返回True,否则False。
查询操作
查询所有对象
1 | all_entries = Entry.objects.all() |
The all() method returns a QuerySet of all the objects in the database.
需要注意的是,最好先判断查询结果是否有效,可以通过 exists()来判断。
1 | entry = Entry.objects.get(pk=123) |
更加高效的方式,直接检查是否有数据返回,上面的操作,还会检查查询结果是否有效。
1 | if some_queryset: |
some_queryset.exists() will do more overall work (one query for the existence check plus an extra one to later retrieve the results) than simply using bool(some_queryset), which retrieves the results and then checks if any were returned.
查询单个对象
1 | Entry.objects.order_by('headline')[0] |
查询运算符
exact
iexact
values() 字段查询
1 | Entry.objects.values('name').get(name='hello') |
返回的数据为dict结构 {‘name’:’hello’}
values_list() 字段列表查询
根据参数查询
1 | Entry.objects.filter(pub_date__year=2006) |
The 1
2
3
4
5
6
7
8
### 链式查询
``` python
Entry.objects.filter(headline__startswith='What')
.exclude(pub_date__gte=datetime.date.today())
.filter(pub_date__gte=datetime.date(2005, 1, 30))
多次过滤查询
1 | q1 = Entry.objects.filter(headline__startswith="What") |
q2 和 q3 都是 q1 查询结果的子集
惰性查询
1 | q = Entry.objects.filter(headline__startswith="What") |
从代码上来看,执行了3次数据库查询操作,而实际上只执行了一次,因为只有当执行到 print(q) 时才会触发数据库查询操作。