0

ダイナミックデータセットを持っていますシリアライザを動的に作成してDjango RESTフレームワークで使用しようとしていますが、追加するダイナミックアトリビュートを処理していないようです。私は、コードを実行するとダイナミックシリアライザを使用したdjango restフレームワークの問題

-- views.py 
class DynamicReadings(generics.ListAPIView): 
    def get_serializer_class(self): 
     site = self.kwargs['site'] 
     devices = Device.objects.filter(reader__site__slug=site).order_by('code') 
     dyn_fields = ['x%s' % a.code for a in devices] 
     return SerializerClassFactory(dyn_fields) 

    def get_queryset(self): 
     ... 
     # the query is correct and returns data 

-- serializers.py 
def SerializerClassFactory(dyn_fields): 
class DynamicSerializer(serializers.Serializer): 
    read_at = serializers.DateTimeField() 

    class Meta: 
     fields = ('read_at') 

    for f in dyn_fields: 
     setattr(DynamicSerializer, f, serializers.FloatField()) 
    DynamicSerializer.Meta.fields += ','.join("'%s'" % f for f in dyn_fields) 

    return DynamicSerializer 

、クラス定義で指定された唯一の属性(read_at)が連載されています。ここでは

はコードです。動的属性のいずれも機能していないようです。

例:

[{ "read_at": "2017-05-07T00:12:29Z"}、{ "read_at": "2017-05-08T00:12:30Z"}]

ここではシェルで作成後のクラスの出力である。また、私が試した

>>> serializer = SerializerClassFactory(['x01', 'x02', 'x03']) 
>>> serializer.__dict__ 
mappingproxy({'__module__': 'xxx.api.serializers', 
'Meta': <class 'xxx.api.serializers.SerializerClassFactory.<locals>.DynamicSerializer.Meta'>, 
'x02': FloatField(), '_declared_fields': OrderedDict([('read_at', DateTimeField())]), 
'__doc__': None, 'x01': FloatField(), 'x03': FloatField()}) 

setattr(DynamicSerializer, f, property(serializers.FloatField())) 
setattr(DynamicSerializer, f, type(serializers.FloatField())) 

私は私が間違っているのかわからないんだが。

答えて

0

ここでは、フィールドのみが動的であり、基本シリアライザは同じです。あなたがより多くのためにreturn DynamicSerializer(dyn_fields=dyn_fields)

を希望get_serializer_class法上の

class DynamicSerializer(serializers.Serializer): 
    read_at = serializers.DateTimeField() 

    class Meta: 
     fields = ('read_at') 

    def __init__(*args, dyn_fields=None, **kwargs): 
     dyn_fields = dyn_fields or [] 
     for field in dyn_fields: 
      self.fields[field] = serializers.FloatField() 

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

views.pyには:それを動作させるために、私たちは、あなたが持っているでしょうserializers.py

上のフィールドのみを変更しますinfo visit http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields

+0

私は__init__メソッドのシグネチャを変更する必要がありました:def __init __(self、dyn_fields = None、* args、** kwargs)。今私は 'DynamicSerializer'オブジェクトが呼び出すことができないエラーを取得しています。 – bah

+0

'get_serializer_class'を上書きしないことが必要なので、この問題が発生しています。ここを見てくださいhttps://github.com/encode/django-rest-framework/blob/master/rest_framework/generics.py#L105-L130 'get_serializer_class'はクラス(呼び出し可能)を返すことを期待していますが、インスタンスは返しません。 'get_serializer()'をオーバーライドする必要があります。 – foobarna

+0

あなたの助けに感謝し、正しい方向に私を指差してください。この場合、問題の原因となる定位置引数は使用できません。ここで参照してください[link](https://github.com/encode/django-rest-framework/issues/4397) – bah

関連する問題