跳到主要内容

Django REST 过滤

在构建 Web API 时,过滤数据是一个常见的需求。Django REST 框架(DRF)提供了强大的过滤功能,允许开发者根据特定条件筛选返回的数据。本文将详细介绍如何在 DRF 中实现过滤功能,并通过实际案例帮助你理解其应用场景。

什么是 Django REST 过滤?

Django REST 过滤是指在 API 请求中根据特定条件筛选数据的过程。例如,你可能希望只返回某个用户的订单,或者只返回价格高于某个值的商品。通过过滤,你可以减少返回的数据量,提高 API 的性能,并满足客户端的需求。

基础过滤

在 DRF 中,最简单的过滤方式是使用 filter_backendsfilterset_fields。以下是一个简单的示例:

python
from rest_framework import generics
from django_filters import rest_framework as filters
from .models import Product
from .serializers import ProductSerializer

class ProductFilter(filters.FilterSet):
class Meta:
model = Product
fields = ['category', 'price']

class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [filters.DjangoFilterBackend]
filterset_class = ProductFilter

在这个示例中,我们定义了一个 ProductFilter 类,并指定了可以根据 categoryprice 字段进行过滤。然后,我们在 ProductList 视图中使用了这个过滤器。

示例请求

假设我们有以下产品数据:

IDNameCategoryPrice
1LaptopElectronics1000
2SmartphoneElectronics800
3HeadphonesAccessories200

如果我们发送以下请求:

GET /products/?category=Electronics

返回的结果将是:

json
[
{
"id": 1,
"name": "Laptop",
"category": "Electronics",
"price": 1000
},
{
"id": 2,
"name": "Smartphone",
"category": "Electronics",
"price": 800
}
]

高级过滤

除了基础过滤,DRF 还支持更复杂的过滤方式,例如范围过滤、搜索过滤和排序。

范围过滤

范围过滤允许你根据某个字段的范围来筛选数据。例如,你可能希望返回价格在某个范围内的商品。

python
class ProductFilter(filters.FilterSet):
min_price = filters.NumberFilter(field_name="price", lookup_expr='gte')
max_price = filters.NumberFilter(field_name="price", lookup_expr='lte')

class Meta:
model = Product
fields = ['category', 'price', 'min_price', 'max_price']

示例请求

GET /products/?min_price=500&max_price=1000

返回的结果将是:

json
[
{
"id": 1,
"name": "Laptop",
"category": "Electronics",
"price": 1000
},
{
"id": 2,
"name": "Smartphone",
"category": "Electronics",
"price": 800
}
]

搜索过滤

搜索过滤允许你根据某个字段的内容进行搜索。例如,你可能希望根据产品名称进行搜索。

python
from rest_framework import filters

class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['name']

示例请求

GET /products/?search=Laptop

返回的结果将是:

json
[
{
"id": 1,
"name": "Laptop",
"category": "Electronics",
"price": 1000
}
]

排序

排序允许你根据某个字段对结果进行排序。例如,你可能希望根据价格对商品进行排序。

python
class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [filters.OrderingFilter]
ordering_fields = ['price']

示例请求

GET /products/?ordering=price

返回的结果将是:

json
[
{
"id": 3,
"name": "Headphones",
"category": "Accessories",
"price": 200
},
{
"id": 2,
"name": "Smartphone",
"category": "Electronics",
"price": 800
},
{
"id": 1,
"name": "Laptop",
"category": "Electronics",
"price": 1000
}
]

实际案例

假设你正在开发一个电商平台的 API,你需要实现以下功能:

  1. 根据商品类别过滤商品。
  2. 根据价格范围过滤商品。
  3. 根据商品名称搜索商品。
  4. 根据价格对商品进行排序。

通过使用 DRF 的过滤功能,你可以轻松实现这些需求。以下是一个完整的示例:

python
from rest_framework import generics, filters
from django_filters import rest_framework as django_filters
from .models import Product
from .serializers import ProductSerializer

class ProductFilter(django_filters.FilterSet):
min_price = django_filters.NumberFilter(field_name="price", lookup_expr='gte')
max_price = django_filters.NumberFilter(field_name="price", lookup_expr='lte')

class Meta:
model = Product
fields = ['category', 'price', 'min_price', 'max_price']

class ProductList(generics.ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [django_filters.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filterset_class = ProductFilter
search_fields = ['name']
ordering_fields = ['price']

总结

Django REST 框架提供了强大的过滤功能,可以帮助你更高效地查询和返回数据。通过使用基础过滤、范围过滤、搜索过滤和排序,你可以轻松实现复杂的查询需求。希望本文能帮助你理解并应用这些功能。

附加资源

练习

  1. 在你的 Django 项目中实现一个简单的过滤功能,根据用户 ID 过滤订单。
  2. 尝试实现一个范围过滤,根据创建日期过滤文章。
  3. 实现一个搜索功能,允许用户根据文章标题搜索文章。

通过完成这些练习,你将更深入地理解 Django REST 过滤的工作原理和应用场景。