过滤从简单到更复杂的示例

普通香草过滤

要筛选任何视图,请覆盖其 get_queryset 方法以返回筛选的查询集

class HREmployees(generics.ListAPIView):
    def get_queryset(self):
        return Employee.objects.filter(department="Human Resources")

然后,所有 API 函数将使用筛选的查询集进行操作。例如,上述视图的列表将仅包含其部门为人力资源的员工。

访问 get_queryset 中的查询参数

基于请求参数的过滤很容易。

self.requestself.argsself.kwargs 可用,并指向当前请求及其过滤参数

def DepartmentEmployees(generics.ListAPIView):
    def get_queryset(self):
        return Employee.objects.filter(department=self.kwargs["department"])

让 API 参数决定要过滤的内容

如果你想要更多的灵活性并允许 API 调用传入参数来过滤视图,你可以插入过滤后端,如 Django Request Framework(通过 pip 安装)

from rest_framework import filters  

class Employees(generics.ListAPIView):
    queryset=Employee.objects.all()
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ("department", "role",)

现在,你可以进行 API 调用/api/employees?department=Human Resources,你将获得仅属于人力资源部门的员工列表,或者仅获取人力资源部门的经理。

你可以将查询集筛选与 Django Filter Backend 结合使用,没有问题。过滤器将对 get_queryset 返回的过滤查询集起作用

from rest_framework import filters  

class HREmployees(generics.ListAPIView):
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ("department", "role",)

    def get_queryset(self):
        return Employee.objects.filter(department="Human Resources")

FilterSets

到目前为止,你可以在上述情况下使用简单类型匹配。

但是,如果你想要一些更复杂的东西,比如年龄在 25 到 32 岁之间的人力资源员工名单呢?

问题的答案:过滤器

过滤器集是定义如何过滤模型的各个字段的类。

像这样定义 em

class EmployeeFilter(django_filters.rest_framework.FilterSet):
    min_age = filters.django_filters.NumberFilter(name="age", lookup_expr='gte')
    max_age = filters.django_filters.NumberFilter(name="price", lookup_expr='lte')     

    class Meta:
        model = Employee
        fields = ['age', 'department']

name 指向要过滤的字段

lookup_expr 基本上是指你在过滤查询集时使用的相同名称,例如你可以使用 lookup_expr="startswith" 进行开始匹配,这相当于 Employee.objects.filter(department__startswith="Human")

然后使用 filter_class 而不是 filter_fields 在视图类中使用它们

class Employees(generics.ListAPIView):
    queryset=Employee.objects.all()
    filter_backends = (filters.DjangoFilterBackend,)
    filter_class = EmployeeFilter

现在你可以做/api/employees?department=Human Resources&min_age=25&max_age=32

不完全匹配和关系

过滤器类和表达式与你在查询集中指定过滤的方式非常相似

你可以使用“__”表示法来过滤关系中的字段,例如,如果部门是员工的外键,则可以添加

filter_fields=("department__name",)

然后你可以做/api/employees?department__name=Human Resources

或者更优雅的是,你可以创建一个过滤器集,添加一个名为 dept 的过滤器变量并将其名称设置为 department__name,允许你进行/api/employees?dept=Human Resources