代码:
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
我正在尝试在update_or_create
的{{1}}的{{1}}方法中进行create
。
但是,模型django-rest-framework
中的字段ModelSerializer
必须为phone_number
。因此,OTP
。
我能够发布unique
并创建对象。但是,再次发布相同的unique=True
会引发错误phone_number
,而不是更新错误(如果已经存在),因为我已经覆盖了phone_number
方法。请帮忙!
答案 0 :(得分:0)
您可以不要求phone_number
,然后手动进行检查。之所以会收到错误,是因为DRF先验证了phone_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
答案 1 :(得分:0)
请尝试在序列化器类而不是模型类中设置验证器。因此,让您的序列化程序类看起来像这样:
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
答案 2 :(得分:0)
您可以使用Signals来做到这一点。简单来说,您可以将created
变量发送到您定义的receiver
,并根据是否创建对象来处理它。在REST响应的情况下,只需重写Serializer中的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