I'm have a dynamic dataset I am trying to use with the Django REST Framework by dynamically creating serializer, but it doesn't seem to process the dynamic attributes I add.
Here is the code:
-- 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
When I execute the code, only the attribute (read_at) specified in the class definition is serialized. None of the dynamic attributes appear to be working.
Example:
[{"read_at":"2017-05-07T00:12:29Z"},{"read_at":"2017-05-08T00:12:30Z"}]
Here is the output of the class after creation in shell:
>>> 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()})
Additionally, I've tried:
setattr(DynamicSerializer, f, property(serializers.FloatField()))
setattr(DynamicSerializer, f, type(serializers.FloatField()))
I'm not sure what I am doing wrong.
Here, only the fields are dynamic, the base serializer is the same. In order to make it work, we will change only the fields on the
DynamicSerializer
in
serializers.py
you would have:and in the
views.py
on theget_serializer_class
method you wouldreturn DynamicSerializer(dyn_fields=dyn_fields)
for more info visit http://www.django-rest-framework.org/api-guide/serializers/#dynamically-modifying-fields