Home > Enterprise >  Use same serializer class but with different action in a view in Django rest framework
Use same serializer class but with different action in a view in Django rest framework

Time:10-28

I have a modelset view in which different customs functions are defined based on the requirement. I have to write another get function in which I want to use the same serializer class. But the field which I have defined in the serializer class in pkfield but for the get function, I want it as a stringfield rather than pk field. How to achieve that??

Also, I have defined depth=1, which is also not working.

class Class(TimeStampAbstractModel):
    teacher = models.ForeignKey(
                                Teacher,
                                on_delete=models.CASCADE,
                                null=True,
                                related_name="online_class",
    )
    subject = models.ForeignKey(
                                Subject,
                                on_delete=models.SET_NULL,
                                null= True,
                                related_name= "online_class",
    )
    students_in_class = models.ManyToManyField(Student, related_name="online_class")

My view:

class ClassView(viewsets.ModelViewSet):
    queryset = Class.objects.all()
    serializer_class = ClassSerializer
    serializer_action_classes = {
        'add_remove_students': AddStudentstoClassSerializer,
        'get_all_students_of_a_class': AddStudentstoClassSerializer,
    }

    def get_serializer_class(self):

        """
            returns a serializer class based on the action
            that has been defined.
        """
        try:
            return self.serializer_action_classes[self.action]
        except (KeyError, AttributeError):
            return super(ClassView, self).get_serializer_class()
        
       def add_remove_students(self, request, *args, **kwargs):
       """ 
       serializer class used is AddStudentstoClassSerializer
       """
       def get_all_students_of_a_class(self,request,pk=None):
       """
       for this I function too, I want to use the same AddStudentstoClassSerializer class but 
       there is a problem. The field students_in_class is already defined as pkfield, whereas I
       want to use it as a stringfields in the response of this function
       """"

My serializer:

class AddStudentstoClassSerializer(serializers.ModelSerializer):
    students_in_class = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Student.objects.all()
    )

    class Meta:
        model = Class
        fields = ["students_in_class"]
        depth = 1

    def update(self, instance, validated_data):
        slug = self.context["slug"]
        stu = validated_data.pop("students_in_class")
        /................other codes....../
        return instance

Here we can see the student_in_class is defined as pkfield which is ok when using the update api, but when I want to use the get api and call get_all_students_of_a_class I want the field to be stringfield or some other field. How to do that? Also depth= 1 is also not working.

CodePudding user response:

You can override you to_representation method like this.

class AddStudentstoClassSerializer(serializers.ModelSerializer):
    students_in_class = serializers.PrimaryKeyRelatedField(
        many=True, queryset=Student.objects.all()
    )

    class Meta:
        model = Class
        fields = ["students_in_class"]
    
    def to_representation(self, instance):
        data = {
            "students_in_class": # Write your logic here
        }
        return data

    def update(self, instance, validated_data):
        slug = self.context["slug"]
        stu = validated_data.pop("students_in_class")
        /................other codes....../
        return instance
  • Related