Abhijeet Pal
Abhijeet Pal

Reputation: 468

Add Extra fields in serializer from one to one relation models

In this project, I have two models Student and Parent related to each other through one to one field.

In Parent serializer, I want to add Students attributes like age. I am thinking of using SerializerMethodField for both cases is their any better way to do it?

I am not getting the queries on how to get the object attributes and little explanation would be great.

Here what I have done till now.

Models.py

class Student(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, default=None)
    batch = models.ForeignKey(Batch, on_delete=models.CASCADE, null=True, related_name='students')
    email = models.EmailField(null=True)
    phone_number = models.CharField(max_length=10, null=True)
    dob = models.DateField(blank=True, null=True, help_text="Enter in the following format : YYYY-MM-DD")
    address = models.TextField(max_length=150, null=True)
    age = models.IntegerField(blank=True)
    image = models.ImageField(upload_to='profile_pictures', default='student_image.png', blank=True)

    @property
    def remarks(self):
        return self.remark_set.all()

    @property
    def marks(self):
        return self.marks_set.all()

    def __str__(self):
        return self.user.firstName + ' ' + self.user.lastName

class Parent(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, default=None)
    child = models.ForeignKey(Student, on_delete=models.CASCADE)
    email = models.EmailField(null=True)
    phone_number = models.CharField(max_length=10, null=True)
    address = models.TextField(max_length=150, null=True)
    image = models.ImageField(upload_to='profile_pictures', default='student_image.png', blank=True)

    def __str__(self):
        return self.user.firstName + ' ' + self.user.lastName


Serilaizer.py

class ParentSerializer(serializers.HyperlinkedModelSerializer):
    student_age = serializers.SerializerMethodField()
    student_batch = serializers.SerializerMethodField()
    parent_name = serializers.SerializerMethodField()

    class Meta:
        model = Parent
        fields = "__all__"

    def get_student_age(self, obj):
        return Parent.objects.get(child__age = self.obj.user.child)

    def get_student_batch(self, obj):
        return Parent.objects.get(child__bacth = self.obj.user.child)

    def get_parent_name(self, user):
        return Parent.objects.get(user=self.request.user)


Views.py

class ParentView( mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet):
    queryset = Parent.objects.all()
    serializer_class = serializers.ParentSerializer

Upvotes: 2

Views: 1119

Answers (1)

mehdi
mehdi

Reputation: 1150

first way:

from apps.models import Student, parent

class BasicUserSerializer(serializers.ModelSerializer):
    class Meta:
       model =  User
       fields = "__all__"


class BasicStudentSerializer(serializers.ModelSerializer):
    class Meta:
       model =  Student
       fields = "__all__"


class ParentSerializer(serializers.ModelSerializer):
    user = BasicUserSerializer(read_only=True,many=False)
    child = BasicStudentSerializer(read_only=True, many=True)

    class Meta:
        model = Parent
        fields = '__all__'

you can do this way . its replace a serializer field that you want and if parent have several child then in child's field you have new all child's information as dictionary.

================================================================

second way is use HyperLinkModel .

class ParentSerializer(serializers.ModelSerializer):
    user = serializers.HyperlinkedRelatedField(read_only=True,many=False)
    child = serializers.HyperlinkedRelatedField(read_only=True, many=True)

    class Meta:
        model = Parent
        fields = '__all__'

but notice that in first way you will have a independent serializer class that every time you need to serialize model class that related to User or Child you can use them simply.

Upvotes: 4

Related Questions