Home > Software engineering >  How to use same serializer class for get and post method in Django?
How to use same serializer class for get and post method in Django?

Time:06-05

I have been trying, but fail miserably, to use only a single serializer class for both post and get api call. I have a Person model which has some fields. What I need is I want to create a person object using post API with certain fields and however needs to show some other fields while doing get request. For eg:

My model:

class Person(models.Model):
    name = models.CharField(max_length=255,blank=True)
    email = models.EmailField(unique=True)
    phone = models.CharField(max_length=16)
    address = models.CharField(max_length=255,blank=True)
    roll = models.IntegerField()
    subject = models.CharField(max_length=255,blank=True)
    college_name = models.CharField(max_length=255,blank=True)

Now my serializer will look like this.

class PersonSerializer(serializers.ModelSerializer):

class Meta:
    model = Student
    fields = ['id','email','name','phone','roll','subject','college_name', 'address']

For eg, I have a view that handles both post and get request (probably using APIView), then what I need to do is, to create a person object I only using name, phone, and email. So for post API call, I only need three fields whereas while calling the get API I only need to display the fields name, roll, subject, and college_name not others.

In this situation, how can I handle using the same serializer class??

CodePudding user response:

You can set fields to be read-only (for GET requests) with the read_only_fields list and write-only (for POST, PUT, PATCH) with the extra_kwargs dictionary, both inside the Serializer's Meta class:

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ['id', 'email', 'name', 'phone', 'roll', 'subject', 'college_name']
        read_only_fields = ['roll', 'subject', 'college_name']
        extra_kwargs = {
            'email': {'write_only': True},
            'phone': {'write_only': True},
        }

CodePudding user response:

First in the model, you need to add the attribute null=True into the non-required fields.

class Person(models.Model):
    name = models.CharField(max_length=255,blank=True)
    email = models.EmailField(unique=True)
    phone = models.CharField(max_length=16)
    # here I added `null=True`
    address = models.CharField(max_length=255,blank=True, null = True)
    roll = models.IntegerField(null = True)
    subject = models.CharField(max_length=255,blank=True, null = True)
    college_name = models.CharField(max_length=255,blank=True, null = True)

And in the serializer, you need to add the extra_kwargs property to set the read-only fields.

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        fields = ['id', 'email', 'name', 'phone', 'roll', 'subject', 'college_name']
        extra_kwargs = {
            'roll': {'read_only': True},
            'subject': {'read_only': True},
            'college_name': {'read_only': True},
        }
  • Related