簡體   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