Dynamic Field Serialization using Serpy

Viewed 873

I was using DRF serializers.ModelSerializerbut with hundred of data to serialize, it's slow and has a huge CPU time.

I've switched to Serpy [GITHUB LINK], it's a great library and REALLY FAST, works like a charm, dropping the serialization time to 50/70% less than the standard DRF ModelSerializers.

Using the DynamicModelSerializer, in DRF, my life was quite easy, in fact, basically, i was able to use the fields=('all') in my old DRF Serializer classed and then, adding the extra exclude parameter, i was able to exclude some unuseful parameters from my serializer, here is the DynamicModelSerializer class:

class DynamicModelSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        fields = kwargs.pop('fields', None)
        add_fields = kwargs.pop('add_fields', None)
        exclude = kwargs.pop('exclude', None)
        nest = kwargs.pop('nest', None)

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

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

        if fields is not None:
            allowed = set(fields)
            existing = set(self.fields.keys())
            for field_name in existing - allowed:
                self.fields.pop(field_name)

        if add_fields is not None:
            for field_name, field_class in add_fields.items():
                ### first pop the old field class from the fields if it's there
                if field_name in self.fields:
                    self.fields.pop(field_name)
                ### now add the field to the fields
                self.fields[field_name] = field_class

        if exclude is not None:
            for field_name in exclude:
                self.fields.pop(field_name)

Now, how i can do that with Serpy? i've tried to subclass the serpy.Serializer class and work around it like shown below:

class SerpyDynamicModelSerializer(serpy.Serializer):

    def __new__(cls, *args, **kwargs):
        if cls.Meta.model:
            fields_list = [setattr(cls, f.name, serpy.Field()) for f in cls.Meta.model._meta.get_fields()]

But, under the hood, it seems that the serializer inherits a second SerializerMeta class and gets ready in that class the fields to serialize.

My goal is to:

  • Serialize all fields by default
  • Have the possibility to add/exclude some extra fields at runtime

It's possible?

Thanks.

0 Answers
Related