2017-02-12 65 views
0

我有一個模型結構,其中一個Outage有許多Product並且每個ProductClient相關聯。過濾領域中的串行器

當我中斷了客戶的名單,我可以使用OutageSerializer確保在停電列出的產品屬於客戶端,像這樣:

class OutageSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Outage 

    def __init__(self, *args, **kwargs): 
     super(OutageSerializer, self).__init__(*args, **kwargs) 
     client_id = self.context.get("client_id") 
     if client_id: 
      if 'products' in self.fields and \ 
        hasattr(self.fields['products'], 'child_relation'): 
       product_ids = ClientManager(client_id).client_products().\ 
        values_list('pk', flat=True) 
       self.fields['products'].child_relation.queryset = \ 
        self.fields['products'].child_relation.queryset.\ 
         filter(id__in=product_ids) 

不過,如果我只是通過RetrieveAPIView獲得單一中斷,child_relation屬性不再可用,因此我必須尋找其他方法。

目前,我正在檢查* args來長,並把該產品領域的過濾器在那裏,就像這樣:

class OutageSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Outage 

    def __init__(self, *args, **kwargs): 
     super(OutageSerializer, self).__init__(*args, **kwargs) 
     client_id = self.context.get("client_id") 
     if client_id: 
      if 'products' in self.fields: 
       if hasattr(self.fields['products'], 'child_relation'): 
        product_ids = ClientManager(client_id).client_products().\ 
         values_list('pk', flat=True) 
        self.fields['products'].child_relation.queryset = \ 
         self.fields['products'].child_relation.queryset.\ 
          filter(id__in=product_ids) 
       elif len(args) == 1 and hasattr(args[0], 'products'): 
        product_ids = ClientManager(client_id).client_products().\ 
         values_list('pk', flat=True) 
        args[0].products = \ 
         args[0].products.filter(id__in=products_ids) 

請記住,該產品領域是不是我想要的只是場過濾。

目前,API僅用於GET。

雖然這種方法「有效」,但似乎有點混亂。 RetrieveAPIView s有什麼過濾列表字段的首選標準方法嗎?

回答

0

如果Product有related_name products FKS到OutageClient比你可以使用SerializerMethodField

class OutageSerializer(serializers.ModelSerializer): 

    products = serializers.SerializerMethodField() 

    def get_products(self, outage): 
     products_qs = outage.products.filter(client=self.context['request'].client) 
     return ProductSerialzier(products_qs, many=True).data 
+0

這對我來說不是一個長期的解決方案。雖然我可以調整以對產品執行類似的過濾,但使用ClientManager獲取客戶端的有效產品,我在上下文中有一個可選的client_id,而不是請求上下文中的強制客戶端。此外,這迫使我爲產品使用特定的序列化程序,使我無法擴展OutageSerializer併爲這些子類提供不同的產品序列化程序。 – Reuben