繁体   English   中英

Django-如何在分派方法中访问过滤的查询集?

[英]Django - How to access filtered queryset in the dispatch method?

我有以下代码:

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()返回整个未经过滤的查询集。

那么,如果有可能的话,如何获取已在分派方法中应用了过滤器的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方法并将过滤后的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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM