我有以下代码:
class MyViewSet(ModelViewSet):
...
filter_backends = (...)
def dispatch(self, request, *args, **kwargs):
response = super(MyViewSet, self).dispatch(
request,
*args,
**kwargs
)
... # do something with the response
return response
在调度方法中,我可以使用 response.data
检索过滤后的数据,因此我假设自定义过滤器后端工作正常。但是,在对查询集应用过滤器后,我也想对查询集做一些事情(例如调用count()
)。问题是self.queryset
和self.get_queryset()
返回整个未筛选的查询集。
那么,如果可能的话,如何获取在调度方法中应用过滤器的查询集版本呢?
filter_queryset
方法。它将使用正在使用的任何过滤器后端对其进行过滤。请参阅GenericAPIView
类中的定义。
def filter_queryset(self, queryset):
"""
Given a queryset, filter it with whichever filter backend is in use.
You are unlikely to want to override this method, although you may need
to call it either from a list view, or from a custom `get_object`
method if you want to apply the configured filtering backend to the
default queryset.
"""
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
因此,您可以像这样过滤查询集,
filtered_queryset = self.filter_queryset(self.get_queryset())
# Then do something with the filtered queryset
请注意,self.filter_queryset(self.get_queryset())
将再次筛选查询集,即使查询集已在以下super
调用期间筛选
super(MyViewSet, self).filter_queryset(
self.queryset()
).
以下是克服重复筛选器调用的一种方法。您可以重写 filter_queryset
方法并将筛选的查询集附加到实例。(请注意,此解决方案未经测试)
即,像这样的东西。
class MyViewSet(ModelViewSet):
...
filter_backends = (...)
def dispatch(self, request, *args, **kwargs):
response = super(MyViewSet, self).dispatch(
request,
*args,
**kwargs
)
... # do something with the response
# After this super call `_filtered_query_set` attribute will be set.
# so use `self._filtered_query_set` wherever needed
return response
def filter_queryset(self, queryset):
filtered_query_set = super(MyViewSet, self).filter_queryset(
self.queryset()
)
self._filtered_query_set = filtered_query_set
return filtered_query_set