【问题标题】:how to update OneToOneField / ForeignKey using ViewSet? Django如何使用 ViewSet 更新 OneToOneField / ForeignKey?姜戈
【发布时间】:2017-06-15 04:54:36
【问题描述】:

我目前正在使用 restful 和序列化程序来创建和更新我的用户。 如果字段与 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

在我看来.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。

有人可以帮我看看我在这里缺少什么或者我可以做些什么来检查吗?

提前致谢

【问题讨论】:

  • instance..school.school_name,你只是在这个 stackoverflow 或你的脚本中打错了吗?
  • @SancaKembang 在 stackoverflow 中:P

标签: python json django serialization model


【解决方案1】:

我认为你的序列化器没有完成...userschool 的字段是实例模型,你需要在你的序列化器中的特定字段来实现实例模型,例如:带有source='...' 参数。

和例子:

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
    )

【讨论】:

  • 我只是尝试过这个,当然我需要使用user_emailEmailField 而不是你应该使用的,但仍然没有运气。我在尝试更新时没有收到任何错误
【解决方案2】:

由于您使用 SerializerMethodField,它是 user_emailschool_name 的只读字段 (docs),因此它们在validated_data

您是否检查了您在 validated_data

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

【讨论】:

    【解决方案3】:

    嵌套的序列化器/模型/演示文稿实际上帮助我完成了工作并且非常有帮助。

    这里也提供了一个例子。 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 包含如何在类和元字段中设置嵌套序列化程序

    【讨论】:

      猜你喜欢
      • 2018-04-12
      • 2015-07-18
      • 2021-03-13
      • 2016-01-18
      • 1970-01-01
      • 2020-08-17
      • 2017-09-20
      • 2016-05-14
      • 2011-08-23
      相关资源
      最近更新 更多