Django - 如何在调度方法中访问过滤的查询集



我有以下代码:

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.querysetself.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

最新更新