数据库查询操作

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
2
for e in Entry.objects.all():
print(e.headline)

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
2
3
4
5
6
7
if Entry.objects.filter(headline="Test"):
print("There is at least one Entry with the headline Test")

# 或者

if Entry.objects.filter(headline="Test").bool():
print("There is at least one Entry with the 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
2
3
entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
do something

更加高效的方式,直接检查是否有数据返回,上面的操作,还会检查查询结果是否有效。

1
2
if some_queryset:
do something

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
2
3
Entry.objects.order_by('headline')[0]

Entry.objects.get(id=3)

查询运算符

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

return a QuerySet containing objects that match the given lookup parameters.
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
2
3
q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(pub_date__gte=datetime.date.today())
q3 = q1.filter(pub_date__gte=datetime.date.today())

q2 和 q3 都是 q1 查询结果的子集

惰性查询

1
2
3
4
q = Entry.objects.filter(headline__startswith="What")
q = q.filter(pub_date__lte=datetime.date.today())
q = q.exclude(body_text__icontains="food")
print (q)

从代码上来看,执行了3次数据库查询操作,而实际上只执行了一次,因为只有当执行到 print(q) 时才会触发数据库查询操作。