【问题标题】:Nested Serialization using SlugRelatedField使用 SlugRelatedField 的嵌套序列化
【发布时间】:2014-09-27 06:18:40
【问题描述】:

我有这样的模型结构:

class Student(models.Model):
    created = models.DateTimeField(editable=False)
    # should modifieid be editable?
    modified = models.DateTimeField(editable=False)
    english_name = models.CharField(max_length=SHORT_LENGTH)
    # TODO: make sure chinese characters work!
    chinese_name = models.CharField(max_length=SHORT_LENGTH)
    # student_id = ####

    def save(self, *args, **kwargs):
        # store curr time ahead so we don't account for processor cycles
        curr_time = timezone.now()

        # if we don't have an ID, we're brand new!
        if not self.id:
            self.created = curr_time
        self.modified = curr_time
        return super(Student, self).save(*args, **kwargs)

class SeminarMembership(models.Model):
    student = models.ForeignKey('Student')
    seminar = models.ForeignKey('Seminar', related_name = "memberships")

class Seminar(models.Model):
    created = models.DateTimeField(editable=False)
    modified = models.DateTimeField()
    #userID = ############
    title = models.CharField(max_length=LONG_LENGTH)
    #description

    def save(self, *args, **kwargs):
        # store curr time ahead so we don't account for processor cycles
        curr_time = timezone.now()

        # if we don't have an ID, we're brand new!
        if not self.id:
            self.created = curr_time
        self.modified = curr_time
        return super(Seminar, self).save(*args, **kwargs)

SeminarMembership 是建立学生-研讨会配对的关键。

我正在尝试让 DRF 序列化一个单独的研讨会实体,以便 JSON 响应包括通过枢轴注册到该研讨会的所有学生。为此,我检索了与某个研讨会相关的所有成员资格 (many=True):

class SeminarSerializer(serializers.ModelSerializer):
    memberships = SeminarMembershipSerializer(many=True)
    class Meta:
        model = Seminar
        read_only_fields = ('title',)

那么,由于 SeminarMembership 的序列化器如下:

class SeminarMembershipSerializer(serializers.ModelSerializer):
    # needs to be read_only?
    student = StudentSerializer(many=False)
    seminar = serializers.PrimaryKeyRelatedField(many=False, read_only=True)

    class Meta:
        model = SeminarMembership

当我将 SeminarSerializer 修改为以下内容时,出现“Student object not serializable”错误:

   class SeminarSerializer(serializers.ModelSerializer):
        memberships = serializers.SlugRelatedField(many=True, read_only=True, slug_field='student')
        class Meta:
            model = Seminar
            read_only_fields = ('title',)

理论上,DRF 应该认识到 SlugRelatedField 应该使用来自 SeminarMembershipSerializer 实现的 StudentSerializer 进行序列化,然后继续序列化外国学生对象字段以用于 JSON 响应。但后来我遇到了一个不能用 JSON 序列化的“学生对象”。

【问题讨论】:

    标签: django serialization django-models django-rest-framework api-design


    【解决方案1】:

    首先,如果 SeminarMembership 中仅有的字段是学生和研讨会,那么简单的 ManyToMany 字段就足够了。如果没有,您应该使用 through 字段来表示此关系 (here are the docs)

    然后,您必须声明一个 SeminarSerializer AND StudentSerializer(您不需要会员序列化器)。

    我正在尝试让 DRF 序列化一个单独的研讨会实体,以便 JSON 响应包括通过枢轴注册到该研讨会的所有学生。

    为此,您必须将您的学生放入您的 SeminarSerializer 中,如下所示:

    class SeminarSerializer(serializers.ModelSerializer):
        students = StudentSerializer(many=True)
        class Meta:
            model = Seminar
            read_only_fields = ('students',)
    

    另外,我强烈建议您使用django-extensions -> TimeStampedModel 而不是添加您自己创建和修改的字段。它非常易于使用,它为您完成所有工作(因此您不再需要覆盖保存功能)。

    【讨论】:

      猜你喜欢
      • 2017-03-25
      • 1970-01-01
      • 2014-07-23
      • 2016-07-29
      • 2016-01-17
      • 1970-01-01
      • 1970-01-01
      • 2019-12-28
      • 1970-01-01
      相关资源
      最近更新 更多