Reputation: 67
I am writing a Django app, which is huge and has a large number of API endpoints. This app uses DRF to serialize the information being sent to the frontend via JSON, and deserialize the information sent via JSON from the frontend.
For ease of explaining my situation, let's consider a simplistic model. So let's say I have a model A
.
class A(models.Model):
field1 = models.CharField(max_length=255)
field2 = models.CharField(max_length=255)
field3 = models.CharField(max_length=255)
I have views for scenarios like these.
field1
, based on which field2
and field3
will be populated and savedfield2
will be shown on every model in the matching querysetfield2
and field3
will be shown on every model in the matching querysetThis brings me to my questions. Should I write one ModelSerializer
each for all the views above? Or does DRF have some facility to specify model field names in the view itself? If serializers are meant to be written on a per-view basis, aren't serializers more tied to views than models?
Thanks for helping me out. Neither the DRF documentation, nor any number of Google searches managed to solve my issue.
Upvotes: 1
Views: 39
Reputation: 7195
You shouldn't have to write a different serializer for every view. Instead you can use several of their features to achieve what you want:
1) For creation using one single field, mark field2
and field3
as read only. This way they won't be considered when validating the input data when you create the model.
2) To decide which fields to show depending on some parameters of the input in the view, or different views, you can dynamically modify the fields of the serializer:
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
Upvotes: 1