【问题标题】:Create OneToOne field user object in Django serialization在 Django 序列化中创建 OneToOne 字段用户对象
【发布时间】:2020-07-12 05:57:27
【问题描述】:

我正在尝试使用我的 Staff 类创建 User 对象。我的员工模型如下所示,

class Staff(models.Model):
    organization = models.ForeignKey(
        Organization, related_name='staff_organization', on_delete=models.CASCADE, blank=True)
    user = models.OneToOneField(
        User, on_delete=models.CASCADE, blank=True)
    phone = models.CharField(max_length=15, blank=True)

    def __str__(self):
        return self.user.username

我的序列化程序类在这里,

# create staff serializer
class StaffSerializer(serializers.ModelSerializer):

    class Meta:
        model = Staff
        fields = "__all__"

    def create(self, validated_data):
        username = validated_data.pop('username')
        email = validated_data.pop('email')
        password = validated_data.pop('password')
        user_instance, created = User.objects.get_or_create(
            username=username, email=email)

        if not created:
            user_instance.set_password(password)

        staff_instance = Staff.objects.create(
            **validate_data, user=user_instance)
        return staff_instance

视图集类,

class StaffViewSet(viewsets.ModelViewSet):
    serializer_class = StaffSerializer
    queryset = Staff.objects.all()
    permission_classes = [permissions.IsAuthenticated]


    def perform_create(self, serializer):
        staff = serializer.save(organization=self.request.user.staff.organization)
        return Response(serializer.data)

我尝试了以下发布请求,

{"username":"tekson", "email":"tekson@gmail.com", "password":"admin"}

但它显示错误

{
    "user": [
        "This field is required."
    ]
}

我不知道如何从员工创建用户对象。请帮我找出这个错误。

【问题讨论】:

  • 员工序列化程序期望“用户”和“电话”作为输入 json 中的键。此外,由于您在输入中发送电子邮件和密码,因此您需要为这些定义序列化器字段并包含在字段部分中
  • 你能帮我定义序列化器字段吗

标签: python django django-rest-framework


【解决方案1】:

另一种方法是,定义一个UserSerializer

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

然后编辑你的StaffSerializer 喜欢这个。

class StaffSerializer(serializers.ModelSerializer):

    user = UserSerializer(many=False)

    class Meta:
        model = Staff
        fields = "__all__"

    def create(self, validated_data):
        user_data = validated_data.pop('user')
        user_instance = User.objects.create(
            username=user_data['username'],email=user_data['email'], password=user_data['password'])
        user_instance.save()
        
        staff_instance = Staff.objects.create(
            **validated_data, user=user_instance)
        staff_instance.save()
        return staff_instance

这种方法的唯一缺点是您必须在发送的帖子数据上保持嵌套关系。因此,您的数据 {"username":"tekson", "email":"tekson@gmail.com", "password":"admin"} 必须更改为类似的内容。

{
    "phone": "",
    "user": {"username":"tekson", "email":"tekson@gmail.com", "password":"admin"}
}

【讨论】:

  • 显示同样的错误,user: this field is required
  • 您必须更改发送数据的格式。你能在这里分享你的帖子数据格式吗?
  • 我不知道为什么,但它显示KeyError: 'password'
  • 在create方法内尝试打印user_data并检查password字段是否存在。
  • 非常感谢。最后,它起作用了。这是我想要的确切条件
【解决方案2】:

确保在set_password() 之后调用user_instance.save()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 2016-01-08
    • 1970-01-01
    • 2010-12-09
    相关资源
    最近更新 更多