Django 和 VueJS 应用程序中的嵌套多项选择字段序列化

Nested Multiple choice field serialize in Django and VueJS app

我有多项选择的嵌套序列化程序,我能够获取值但是在补丁调用期间 subjects 没有得到更新

这里User和Subject是两个模型,

**Model.py**

class Subject(models.Model):
    uid = models.AutoField(verbose_name='ID', 
                                  serialize=False, 
                                  auto_created=True, 
                                  primary_key=True)
    ENG = "ENGLISH"
    HND = "HINDI"

    SUBJECT = (
        (ENG, "English"),
        (HND, "Hindi"),
    )

    subject = models.CharField(
        max_length=50, choices=SUBJECT, default=ENG)

    def __str__(self):
        return self.subject


class User(AbstractUser):
    uid = models.AutoField(verbose_name='ID', 
                                  serialize=False, 
                                  auto_created=True, 
                                  primary_key=True)
    TEACHER = "Teacher"
    STUDENT = "Student"

    user_type = models.CharField(max_length=30, default=STUDENT)
    approved = models.BooleanField(default=True)

    def save(self, *args, **kwargs):
        if self.user_type == User.TEACHER and self._state.adding:
            self.approved = False
        super().save(*args, **kwargs)

    @property
    def syllabus(self):
        ret = self.teacher.syllabus_set.all()
        if ret:
            return ret
        else:
            return ''

这是我的序列化程序调用


**serializers.py**

class TeacherProfileDetails(serializers.ModelSerializer):
    logger = logging.getLogger(__name__)
    teacher_date = AvailabilityDetails(many=True, read_only=True)
    first_name = serializers.CharField(source='user.first_name', read_only=True)
    last_name = serializers.CharField(source='user.last_name', read_only=True)
    cities = CitySerializer(many=True, read_only=True)
    subject = serializers.SerializerMethodField()
    user = UserDetailsSerializer(read_only=True)

    class Meta:
        model = Teacher
        fields = ('user', 'first_name', 'last_name', 
                  'bio', 'teacher_cost', 'subject', 'teacher_date', 'cities')

    def get_subject(self, obj):
        subject_list = []
        for i in obj.subject.all():
            subject_list.append(i.subject)
        return subject_list

这是我的 views.py 通话

**views.py**

class TeacherListCreateAPIView(APIView):
        logger = logging.getLogger(__name__)

        #def create(self, request, *args, **kwargs):
        def get(self, request, *args, **kwargs):
            self.logger.info("Geeting TeacherListCreateAPIView information")
            teacherList = Teacher.objects.filter(user__username=kwargs["username"])
            self.logger.info(teacherList)
            serializers = TeacherProfileDetails(teacherList, many=True)
            self.logger.info(serializers.data)
            return Response(serializers.data)
        def patch(self, request, *args, **kwargs):
            teacher = Teacher.objects.get(user__username=kwargs['username'])
            serializers = TeacherProfileDetails(data=request.data, instance=teacher)
            self.logger.info(serializers)
            if serializers.is_valid():
                serializers.save()
                return Response(serializers.data, status=status.HTTP_201_CREATED)
            return Response(serializers.errors, status=status.HTTP_400_BAD_REQUEST)

这里是urls.py

path('teacher/<str:username>/details',
         TeacherListCreateAPIView.as_view(), name="teacher-details"),

问题:

我能够获取教师的详细信息,但是补丁调用没有更新主题,看起来我在序列化主题

时在 TeacherProfileDetails 中犯了一些错误

SerializerMethodField只读。因此,提供的序列化程序中的所有字段都是只读的。

您可以改用 SlugRelatedField 序列化程序,用于读取和写入:

subjects = serializers.SlugRelatedField(
    many=True,
    slug_field='subject',
    queryset=Subject.objects.all(),
)

为了更好地在视图中添加逻辑,使 subjects 包含独特的元素,甚至允许将 patch 中的一个主题添加到已经存在的主题中。


或者您可以使用两个单独的序列化器 - 一个用于读取(当前的),一个用于写入(只允许更改字段 - 它可以是 SlugRelatedField,或者甚至只是带有自定义 update() 的 ListField方法逻辑等)。