Description
First of all thanks for this project, i can't use Django without drf π
Im looking for a way to override serializers.ModelSerializer globally
Little bit of context:
Our application is grown big and we want to switch django backend from BigAutoField to SnowflakeAutoField.
My problem:
- ts/js (My frontend) do not support numbers over 2^52,
- I don't want to use Bigint in ts
- i don't want to touch MAX_SAFE_INTEGER
So the best solution in my opinion is to serialize bigint as string.
class SnowflakeField(serializers.Field):
def to_representation(self, value):
return str(value)
def to_internal_value(self, data):
try:
return int(data)
except ValueError:
raise serializers.ValidationError("Invalid integer value")
class SnowflakeModelSerializer(serializers.ModelSerializer):
"""
Snowflake is a bigint so convert to string to avoid frontend memory handling problems
"""
def build_standard_field(self, field_name, model_field):
field_class, field_kwargs = super().build_standard_field(field_name, model_field)
# Use BigIntAsStringField per BigIntegerField
if isinstance(model_field, models.BigIntegerField):
field_class = SnowflakeField
return field_class, field_kwargs
Anyway, since django uses bigint as id, serializing it as sting could be a better option in any case since the id can grow big
Possible ways
- use my custom serializer around the code (not so clean)
class MyModelSerializer(SnowflakeModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
- Write a Custom JsonRender and JsonParser
and do something like this with a lot of assumptions, spoiler bad programming
class SnowflakeJSONRenderer(JSONRenderer):
def _convert_big_integers(self, obj):
if isinstance(obj, dict):
return {key: self._convert_big_integers(value) for key, value in obj.items()}
elif isinstance(obj, list):
return [self._convert_big_integers(item) for item in obj]
elif isinstance(obj, int) and obj > 2**53:
return str(obj)
return obj
What im looking for
As far as i know there is no option to do this
REST_FRAMEWORK = {
'DEFAULT_MODEL_SERIALIZER_CLASS': 'path.to.utils.serializers.CustomModelSerializer',
}
Am i missing something? In your opinion what could be the best solution? I'm open to any suggestion