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},
}