Dhruv Bhanushali
Dhruv Bhanushali

Reputation: 67

Are ModelSerializers meant to be written on a per-view basis?

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.

This 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

Answers (1)

dukebody
dukebody

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

Related Questions