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.