Django中StoreCheckout模型重写save与clean方法条件不生效排查
Django模型save、clean方法不生效问题修复方案
问题根因
clean方法实现错误:方法末尾错误调用了父类的save方法,而非父类的clean方法,导致校验逻辑执行异常,还会产生重复保存的问题- Django默认规则限制:直接调用模型实例的
save()方法不会自动触发clean校验,只有通过ModelForm、Admin后台等途径保存时才会自动执行clean逻辑 - 潜在时区问题:使用原生
datetime.now()生成时间,若项目开启时区配置USE_TZ = True会出现时间不兼容告警
修复步骤
- 修正
clean方法的父类调用逻辑,将末尾的父类save调用改为clean调用 - 在重写的
save方法开头主动调用full_clean(),触发自定义校验逻辑 - 替换
datetime.now()为Django提供的时区安全的时间生成方法django.utils.timezone.now()
修正后完整代码
from django.db import models from django.core.exceptions import ValidationError from django.utils import timezone from django.conf import settings # 此处补充导入你项目内的Store模型、bank_number_validate校验器 class StoreCheckout(models.Model): store = models.ForeignKey( to=Store, on_delete=models.CASCADE, limit_choices_to={ 'is_confirm': True }, ) pay_date = models.DateTimeField() amount = models.PositiveBigIntegerField() bank_number = models.PositiveBigIntegerField(validators=[bank_number_validate]) def __str__(self): return self.store.name def save(self, *args, **kwargs): # 主动触发所有字段、自定义校验逻辑 self.full_clean() if not self.bank_number: self.bank_number = self.store.bank_number if not self.pay_date: self.pay_date = timezone.now() super().save(*args, **kwargs) def clean(self, *args, **kwargs): if not settings.MIN_CHECKOUT <= self.store.wallet <= settings.MAX_CHECKOUT: raise ValidationError( f'amount of your store must between {settings.MIN_CHECKOUT} and {settings.MAX_CHECKOUT} toman' ) # 调用父类clean方法执行默认校验规则 super().clean(*args, **kwargs)
内容的提问来源于stack exchange,提问作者Ali Rahmani
相关产品推荐
相关产品推荐

