当前位置: 首页 > 知识库问答 >
问题:

如何在ModelSerializer的创建方法中实现update_or_create

东方明亮
2023-03-14

守则:

class OTP(AppModel):
    phone_regex = RegexValidator(regex=r'^[6789]\d{9}$', message="phone no. is invalid.")
    phone_number = models.CharField(validators=[phone_regex], max_length=10, unique=True)
    code = models.CharField(max_length=255)

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

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')

    @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

我试图在django rest框架ModelSerializercreate方法中执行update\u或\u create

但是,型号OTP内的phone\u number字段必须是唯一的。因此,unique=True

我可以发布一个电话号码并创建对象。但是,再次发布相同的电话号码会抛出错误otp,因为此电话号码已经存在,而不是更新它(如果它已经存在),因为我已经覆盖了create方法。请帮忙!


共有3个答案

暨承平
2023-03-14

您可以使用信号以干净的方式执行此操作。简单地说,您可以将创建的变量发送到您定义的接收器,并根据对象是否创建来处理它。在REST响应的情况下,只需重写序列化程序中的create方法,根据您所处的状态返回数据,或者重写APIView中使用的get/post/patch方法,不返回Serializer.data,而是返回您想要的任何数据。以下是信号接收器的示例:

@receiver(post_save, sender=settings.OTP_MODEL)
def update(sender, instance=None, created=False, **kwargs):
    if created:
        # Do Something
    else:
        # Do Some Other thing
于嘉许
2023-03-14

尝试在序列化程序类中而不是在模型类中设置验证器。让序列化程序类看起来像这样:

class OTPSerializer(serializers.ModelSerializer):
    code = serializers.CharField(max_length=None, required=False)
    phone_regex = RegexValidator(regex=r'^[6789]\d{9}$', message="phone no. is invalid.")  # add this line
    phone_number = serializers.CharField(validators=[phone_regex])  # and this line
    
    class Meta:
        model = OTP
        fields = ('id', 'code', 'phone_number')
        read_only_fields=('id', 'code')

    @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
车子平
2023-03-14

您可以将电话号码设置为不需要,然后手动进行检查。您会得到错误,因为DRF在您验证之前验证了电话号码。因此,基本上,解决方案可以是以下(仅限serialiser代码):

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
 类似资料:
  • 请指导我如何将所有这些转换为asynctask方法。我必须在asynctask中生成这段代码,因为在uithread中调用它时,它给出了一个null值。请告诉我如何实现这一点的正确方法。我看到了很多关于stackoverflow的问题,但我无法做到这一点。 我看到了以下问题: 如何修复android.os.NetworkOnMainThreadException? android.os.Netwo

  • 问题内容: 我有以下方法: 我想使其成为一种通用方法,这样我就不必为每个新的自定义类型编写新的代码。我可以这样做,这需要在调用update()之前实例化该对象: 出于好奇,我想知道是否有一种方法可以使用Java泛型来做到这一点: 有没有办法用Java做到这一点? 问题答案: 请注意,在这种情况下将可以修复。任一(其本身包括可从获得)或本身已得到通过。

  • 我正在尝试创建一个testNG dataprovider方法,该方法将从我的项目中返回一个自定义类的对象数组。这个数组是一维数组,我不想从这个dataprovider方法返回二维数组。请建议,Dataprovider是否应始终返回2D数组(不小于或大于2D)。如果是,则我需要以下方面的帮助: 返回新对象[][]{{user[0]},{user[1]},{user[2]},{user[3]}} 我们

  • 问题内容: 我想编写一种从出生日期开始计算年龄的方法,逻辑是否正确以及如何在android Java中编写它: 问题答案: 这是我对问题的解决方案: 我使用DatePicker获取此处所需的输入值。此方法与日期选择器一起专门用于获取用户的DoB并计算其年龄。根据您的特定实现,可以进行少许修改以允许用户DoB的String输入。String的返回类型是用于更新TextView的,可以稍作修改以允许类

  • 问题内容: 如何在method内部创建方法?当我创建其显示错误时: 令牌无效@上的语法错误 如果不能在方法内部创建方法,那么请告诉我如何在方法外部创建方法,并从方法中传递方法。 问题答案: *请注意,应使用没有不等号的实际类型(例如“ int”和“ short”)替换此类标记。

  • 我正在用java制作一个虚数图形计算器(使用bi={a,b}),并希望为 - * / 和^运算符制作新函数,因为它们不适用于双[]变量。我知道如何制作普通的方法,比如File(),但是我在做像int.getRed()这样的事情时遇到了麻烦。这是我的加法代码 我的添加部分是正确的,我只是找不到任何让函数更“逼真”的东西,比如有人能帮我吗?一旦我弄明白这一点,我应该知道如何做其他的。非常感谢!