使用相同的序列化器 class 但在 Django rest 框架的视图中使用不同的操作

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

我有一个模型集视图,其中根据要求定义了不同的海关功能。我必须编写另一个 get 函数,我想在其中使用相同的序列化器 class。但是我在 pkfield 的序列化程序 class 中定义的字段,但对于 get 函数,我希望它作为 stringfield 而不是 pk 字段。如何实现??

另外,我定义了depth=1,也是不行的。

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")

我的看法:

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
       """"

我的序列化器:

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

这里我们可以看到 student_in_class 被定义为 pkfield,这在使用更新 api 时是可以的,但是当我想使用 get api 并调用 get_all_students_of_a_class 我希望该字段是 stringfield 或其他字段。怎么做?另外 depth= 1 也不起作用。

更新:

尝试以下但仍然无法正常工作:

def to_representation(self, instance):
    rep = super().to_representation(instance)
    # rep["students_in_class"] = instance.students_in_class
    rep['students_in_class'] = StudentSerializer(instance.students_in_class).data
    return rep

class StudentSerializer(serializers.ModelSerializer):
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    class Meta:
        model = Student
        fields = ['user', 'college_name', 'address']

我得到的回复是

{
    "students_in_class": {}
}

这是空字典。应该做什么!

您可以像这样重写 to_representation 方法。

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