在可写嵌套Serializer上获取或创建功能

时间:2016-02-08 22:26:25

标签: python django django-rest-framework

假设我有以下型号:

Order(models.Model):
    user = models.ForeignKey('User')
    ...

User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=100)
    ...

注意:USERNAME_FIELD = 'email'

创建新订单时,我希望使用提供的电子邮件将其链接到客户,或者如果客户不存在则创建客户。

<小时/> 这是我到目前为止所尝试的:

serializers.py:

class OrderSerializer(serializers.ModelSerializer):
    customer = UserSerializer(many=False)

    class Meta:
        model = Order

    def create(self, validated_data):
        user_data = validated_data.pop('user')

        # Get or create a User
        user, created = User.objects.get_or_create(
            email=user_data['email'],
            defaults={
                'email': user_data['email']
            }
        )
        order = Order.objects.create(user=user, **validated_data)
        return order

问题是,如果用户存在,我会收到400“电子邮件已存在”错误。

1 个答案:

答案 0 :(得分:0)

为此,我必须在User上禁用唯一验证器。考虑到在从不同端点创建用户时我需要那些验证器,这似乎是一个坏主意。

email必须是唯一的,嵌套的序列化程序运行UserSerializer的valdiation。

相反,我创建了另一个名为OrderUserSerializer的序列化程序,如下所示:

<强> serializers.py

class OrderUserSerializer(serializers.Serializer):
    email = serializers.EmailField(max_length=200)


class OrderSerializer(serializers.ModelSerializer):
    user = OrderUserSerializer(many=False)

    class Meta:
        model = Order

    def create(self, validated_data):
        user_data = validated_data.pop('user')

        user, created = User.objects.get_or_create(
            email=user_data['email'],
            defaults={
                'email': user_data['email']
            }
        )

        order = Order.objects.create(user=user, **validated_data)
        return order