Skip to content

在Django中如何使用过滤器进行查询

在Django中,过滤器查询主要用于从数据库中检索出符合条件的数据对象。Django的ORM(对象关系映射)系统允许我们使用一种类似SQL的方式,但通过Python的语法来构建查询。下面是一份简单的Django过滤器查询解析指南。

基本概念

Django查询集(QuerySet)是模型的一个数据集合,可以对其进行过滤、排序、切片等操作。查询集是惰性执行的,这意味着只有在需要的时候才会从数据库中获取数据。

基本过滤器

Django提供了多种方法来构建查询集,其中最常用的是filter()exclude()get()

filter()

filter()方法用于返回一个满足条件的数据子集。

python
from myapp.models import Book

books = Book.objects.filter(author='张三')

exclude()

exclude()方法用于返回一个不满足条件的数据子集。

python
books = Book.objects.exclude(author='张三')

get()

get()方法用于获取单个对象;如果结果数量不为1,则抛出异常。

python
book = Book.objects.get(id=1)

字段查询

Django允许我们根据模型的字段进行查询。

python
# 查询价格大于20的书
books = Book.objects.filter(price__gt=20)

# 查询标题以“编程”开头的书
books = Book.objects.filter(title__startswith='编程')

# 查询出版日期在2020年之后的书
books = Book.objects.filter(publication_date__year__gt=2020)

连锁条件

可以通过链式调用过滤器来指定多个查询条件。

python
books = Book.objects.filter(author='张三').filter(publication_date__year__gt=2020)

也可以使用Q对象来创建复杂的查询条件,包括ANDOR等逻辑。

python
from django.db.models import Q

# 查询作者为张三或者出版日期在2020年之后的书
books = Book.objects.filter(Q(author='张三') | Q(publication_date__year__gt=2020))

排序

可以使用order_by()方法对查询集进行排序。

python
# 按照出版日期从早到晚排序
books = Book.objects.order_by('publication_date')

# 按照价格从高到低排序
books = Book.objects.order_by('-price')

切片

可以通过切片(slicing)来限制返回的结果数量或者获取一部分结果。

python
# 获取前10本书
books = Book.objects.all()[:10]

# 分页:获取第11到第20本书
books = Book.objects.all()[10:20]

关联查询

对于关联字段,Django提供了多种方式来查询相关联的对象。

正向查询

假设一个Book模型和一个Author模型,其中Book有一个外键指向Author

python
# 查询所有张三写的书
books = Book.objects.filter(author__name='张三')

反向查询

如果要查询某个Author写的所有书,可以通过反向查询实现。

python
# 假设Author模型中定义了related_name='books'
author = Author.objects.get(name='张三')
books = author.books.all()

# 或者不定义related_name,则使用默认的<model名>_set
books = author.book_set.all()

常用的查询修饰符

Django提供了一些方便的查询修饰符,比如__exact(精确匹配)、__iexact(忽略大小写的精确匹配)、__contains(包含)、__icontains(忽略大小写的包含)、__in(在列表中)、__gt(大于)、__gte(大于等于)、__lt(小于)、__lte(小于等于)、__year(年份)等。

注意事项

  • 查询集是惰性的,这意味着只有在需要的时候才会执行数据库查询。
  • 使用all()方法可以获取模型的所有对象。
  • 使用count()方法可以获取查询集中的对象数量。
  • 使用exists()方法可以快速检查查询集是否包含任何对象。