首页 > 解决方案 > 如何在 ModelSerializer 的 create 方法中实现 update_or_create

问题描述

编码:

类 OTP(AppModel):
    phone_regex = RegexValidator(regex=r'^[6789]\d{9}$', message="电话号码无效。")
    phone_number = models.CharField(validators=[phone_regex], max_length=10, unique=True)
    代码 = models.CharField(max_length=255)

    def __str__(self):
        返回 str(self.phone_number) + ": "+str(self.code)

类 OTPSerializer(serializers.ModelSerializer):
    code = serializers.CharField(max_length=None, required=False)
    元类:
        型号 = OTP
        字段 = ('id', 'code', 'phone_number')
        read_only_fields=('id', 'code')

    @transaction.atomic
    定义创建(自我,验证数据):
        phone_number = 已验证数据.pop("phone_number")
        otp, 创建 = OTP.objects.update_or_create(
            phone_number=phone_number,默认值={"code": generate_otp()})
        返回 otp

我正在尝试在's的方法update_or_create里面做。createdjango-rest-frameworkModelSerializer

但是,phone_number模型内的字段OTP必须是unique. 因此unique=True.

我能够发布phone_number并创建对象。但是,phone_number再次发布相同的内容会引发错误otp with this phone number already exists,而不是在它已经存在时更新它,因为我已经覆盖了该create方法。请帮忙!

标签: pythondjangodjango-modelsdjango-rest-framework

解决方案


您可以phone_number不要求,然后手动进行检查。您会收到错误消息,因为 DRFphone_number在您执行之前已验证。因此,基本上,解决方案可能如下(仅序列化代码):

class OTPSerializer(serializers.ModelSerializer):
    code = serializers.CharField(max_length=None, required=False)
    class Meta:
        model = OTP
        fields = ('id', 'code', 'phone_number')
        read_only_fields=('id', 'code')
        extra_kwargs = {'phone_number': {'required': False}}

    @transaction.atomic
    def create(self, validated_data):
        phone_number = validated_data.pop("phone_number")
        otp, created = OTP.objects.update_or_create(
        phone_number=phone_number, defaults={"code": generate_otp()})
        return otp

推荐阅读