如何使用ViewSet更新OneToOneField / ForeignKey? Django的

时间:2017-01-30 04:29:13

标签: python json django serialization model

我目前正在使用restful和serializers来创建和更新我的用户。 不知何故,如果该字段与OneToOneField / ForeignKey有关,我无法更新某些字段。

在我的models.py中,我的学生实际上连接到django内置的用户模型,其中包含用户的电子邮件并连接到具有学校名称的学校模型

class Student(Model):
    user = OneToOneField(settings.AUTH_USER_MODEL, on_delete=CASCADE)

    date_of_birth = DateField(blank=True, null=True)

    student_name = CharField(max_length=256)
    school = ForeignKey(School,
                        on_delete=CASCADE,
                        related_name="%(class)ss",
                        related_query_name="%(class)s",
                        blank=True,
                        null=True)

在serializer.py中我有

class StudentSerializer(ModelSerializer):
    user_email = SerializerMethodField()
    school_name = SerializerMethodField()

    class Meta:
        model = Student
        fields = (
            'user_email', 'student_name', 'phone', 'school_name')

    def get_user_email(self, obj):
        return obj.user.email

    def get_school_name(self, obj):
        return obj.school.school_name

    def create(self, validated_data):
        return Student.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.user.email = validated_data.get('user_email', instance.user.email)
        instance.student_name = validated_data.get('student_name', instance.student_name)
        instance.phone = validated_data.get('phone', instance.phone)
        instance.school.school_name = validated_data.get('school_name', instance.school.school_name)
        instance.save()
        return instance

在我的view.py更新功能

class UserViewSet(ViewSet):
    queryset = Student.objects.all()

    def update(self, request, pk=None):
        student = get_object_or_404(self.queryset, pk=pk)
        serializer = StudentSerializer(student, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({'status': True})
        return Response({'status': False, 'message': serializer.errors})

我可以使用API​​视图传入json并更新student_namephone,但对于其他两个,user_emailschool_name我不是能够更新它。当我提交json时,我没有得到任何错误输出。

我意识到我无法更新的两个字段是因为它们是OneToOneField / ForeignKey。

有人可以帮我解决一下我在这里缺少的东西,或者我可以做些什么来检查?

提前致谢

3 个答案:

答案 0 :(得分:2)

我认为您的序列化程序未完成...... userschool的字段是实例模型,您需要在序列化程序中使用特定字段来实现实例模型,例如:with {{ 3}}论证。

和示例:

class VoteSerializer(serializers.ModelSerializer):
    # by `username`
    user = serializers.CharField(
        source='user.username',
        read_only=True
    )
    # by `pk/id`
    candidate = serializers.IntegerField(
        source='candidate.pk',
        read_only=True
    )

    class Meta:
        model = Vote
        fields = ('user', 'candidate', 'score')

    def create(self, validated_data):
        return Vote.objects.create(**validated_data)

在你的情况下,或许就是这样;

class StudentSerializer(ModelSerializer):
    # by `pk/id` from the user
    user = serializers.IntegerField(
        source='user.pk',
        read_only=True
    )
    school = serializers.IntegerField(
        source='school.pk',
        read_only=True
    )

答案 1 :(得分:0)

由于您使用 SerializerMethodField ,这是 user_email school_name 的只读字段(docs),因此它们不会是可在 validated_data

中找到

您是否在 validated_data

中查看了您收到的数据
def update(self, instance, validated_data):
    print('++'*22, validated_data)
    return instance

答案 2 :(得分:0)

嵌套的seriailzer / model / presentation实际上帮助我完成了工作并且非常有帮助。

此处还提供了一个示例。 http://www.django-rest-framework.org/api-guide/serializers/#writing-update-methods-for-nested-representations

以上是继续 http://www.django-rest-framework.org/api-guide/serializers/#writing-create-methods-for-nested-representations,其中包含如何在类和元字段中设置嵌套序列化程序