Add a non-model field on a ModelSerializer in DRF 3
Just an example might help you.
class ExtensibleModelSerializerOptions(serializers.SerializerOptions):
"""
Meta class options for ModelSerializer
"""
def __init__(self, meta):
super(ExtensibleModelSerializerOptions, self).__init__(meta)
self.model = getattr(meta, 'model', None)
self.read_only_fields = getattr(meta, 'read_only_fields', ())
self.non_native_fields = getattr(meta, 'non_native_fields', ())
class ExtensibleModelSerializer(serializers.ModelSerializer):
_options_class = ExtensibleModelSerializerOptions
def restore_object(self, attrs, instance=None):
"""
Deserialize a dictionary of attributes into an object instance.
You should override this method to control how deserialized objects
are instantiated.
"""
for field in self.opts.non_native_fields:
attrs.pop(field)
return super(ExtensibleModelSerializer, self).restore_object(attrs, instance)
Source: https://github.com/tomchristie/django-rest-framework/issues/951
class Foo(models.Model):
. . .
@property
def my_field(self):
return stuff
. . .
Source:
Django REST Framework: adding additional field to ModelSerializer
class MySerializer(serializers.ModelSerializer):
write_only_char_field = serializers.CharField(write_only=True)
write_only_list_char_field = serializers.ListField(child=serializers.CharField(max_length=100, default=''), write_only=True)
empty_method_field = serializers.SerializerMethodField()
read_only_custom_model_field = serializers.CharField(source='custom_property', read_only=True)
def create(self, validated_data):
validated_data.pop('write_only_char_field', None)
validated_data.pop('write_only_list_char_field', None)
return super().create(validated_data)
The serializers.CharField(write_only=True)
and serializers.ListField(...)
is a good solution to provide extra data to your .create()
and .update()
methods, as either a single string or a list of strings (you can mix ListField
with other serializer field types).
With this method, you can also define def validate_write_only_char_field
to implement some quick and simple validation.
serializers.SerializerMethodField()
allows you to add some custom read-only field to your serializer output from a method defined on the serializer.
The read_only_custom_model_field
would use a method on your model to read some data, not strictly a model field, but a custom method. I.e.
class MyModel(models.Model):
my_field = models.CharField(max_length=100)
@property
def custom_property(self):
return "Perform calculations, combine with related models, etc. etc."