2017-05-08 55 views
0

我發現我的drf視圖太慢,因爲來自DB的胖SQL SELECT子句。 所以我想選擇只能通過綁定的串行所需的列,因此我可以寫我的視圖類是這樣的:給一個ModelSerializer,我可以獲得用於QuerySet.only的相關模型字段嗎?

class ProductSerializer(serializers.ModelSerializer): 
    company_id = serializers.IntegerField(source='company_id') 
    company_name = serializers.serializers.CharField(source='company.name') 

    class Meta: 
     fields = (
      'id', 'name', 'company_id', 'company_name' 
     ) 

class ListRetrieveProductViewSet(UpdateNonExistentMixin, viewsets.ReadOnlyModelViewSet): 
    queryset = Product.objects.all() 
    serializer_class = ProductSerializer 

    def get_queryset(self): 
     return self.queryset.select_related(
      'company' 
     ).only(*self.serializer_class.get_model_field_names()) 

self.serializer_class.get_model_field_names()可能導致['id', 'name', 'company_id', 'company__name']

如何實現get_model_field_names還是有任何現有的實現?

回答

2

我會再試一次。沒有自動方式(禁止第三方包)執行company_name到company__name的轉換。你可以做的是創造元下另一個變量:

class Meta: 
    fields = (
     'id', 'name', 'company_id', 'company_name' 
    ) 
    fields_for_query = (
     'id', 'name', 'company_id', 'company__name' 
    ) 

然後取它像這樣:

list(self.get_serializer_class().Meta.fields_for_query) 

這種方法使得它更易於管理的一點,因爲他們是彼此的旁邊。通常情況下,您會將獲取方法變成mixin,如下所示:

class FieldForQueryMixin(object): 
    def get_field_for_query(self): 
     assert hasattr(self.get_serializer_class().Meta, 'fields_for_query'), 'Serializer Meta is missing fields_for_query field yo.' 
     return list(self.get_serializer_class().Meta.fields_for_query) 

# use like so 
class ListRetrieveProductViewSet(UpdateNonExistentMixin, FieldForQueryMixin, viewsets.ReadOnlyModelViewSet): 
    pass 
+0

序列化程序字段並非都直接從模型字段派生。他們可能來自模型方法,關係對象和其他東西。 – wonder

+0

@wonder是我在編輯之前回答。道歉。 –

+0

謝謝!你給了比我更優雅的方式。順便說一下,'get_field_for_query'不是一種常規的視圖方法。 – wonder

相關問題