2016-05-25 8 views
4

私はdepthがそれぞれのMetaクラスに設定されたネストされたシリアライザのセットを持っています。ビューで渡されるパラメータに基づいてプログラムの深度を変更したいと思います。Django Rest Frameworkのネストされたシリアライザで深さを動的に変更する方法は?

class ResourceSerializer(serializers.ModelSerializer): 
    type   = serializers.PrimaryKeyRelatedField(queryset=EntityType.objects.all()) 
    tags   = serializers.PrimaryKeyRelatedField(queryset=Tag.objects.all(), many=True) 

    class Meta: 
     model = Resource 
     fields = ('id', 'type', 'uri', 'tags', 'created_date') 
     depth = 1 

残念ながら、実行時にdepth属性をオーバーライドする方法があるようには思えません。私の現在の解決策は、「浅い」シリアライザを継承し、メタクラスをオーバーライドして深さを調整することでした。

class ResourceNestedSerializer(ResourceSerializer): 
    class Meta(ResourceSerializer.Meta): 
     depth = 2 

そして、私の意見で:

if nested: 
     serializer = ContainerNestedSerializer(containers, many=True) 
    else: 
     serializer = ContainerSerializer(containers, many=True) 
    return Response(serializer.data) 

serializer.dataを呼び出す前にdepthを調整する方法はありますか?

答えて

3

ここでは、フィールドの挿入/除外と深さの動的調整を組み込んだコードを示します。あなたの好みに合わせて調整してください。 :)

class DynamicModelSerializer(serializers.ModelSerializer): 
""" 
A ModelSerializer that takes an additional `fields` argument that 
controls which fields should be displayed, and takes in a "nested" 
argument to return nested serializers 
""" 

def __init__(self, *args, **kwargs): 
    fields = kwargs.pop("fields", None) 
    exclude = kwargs.pop("exclude", None) 
    nest = kwargs.pop("nest", None) 

    if nest is not None: 
     if nest == True: 
      self.Meta.depth = 1 

    super(DynamicModelSerializer, self).__init__(*args, **kwargs) 

    if fields is not None: 
     # Drop any fields that are not specified in the `fields` argument. 
     allowed = set(fields) 
     existing = set(self.fields.keys()) 
     for field_name in existing - allowed: 
      self.fields.pop(field_name) 

    if exclude is not None: 
     for field_name in exclude: 
      self.fields.pop(field_name) 
関連する問題