過濾從簡單到更復雜的示例
普通香草過濾
要篩選任何檢視,請覆蓋其 get_queryset
方法以返回篩選的查詢集
class HREmployees(generics.ListAPIView):
def get_queryset(self):
return Employee.objects.filter(department="Human Resources")
然後,所有 API 函式將使用篩選的查詢集進行操作。例如,上述檢視的列表將僅包含其部門為人力資源的員工。
訪問 get_queryset 中的查詢引數
基於請求引數的過濾很容易。
self.request
,self.args
和 self.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