You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中StoreCheckout模型重写save与clean方法条件不生效排查

Django模型save、clean方法不生效问题修复方案

问题根因

  • clean方法实现错误:方法末尾错误调用了父类的save方法,而非父类的clean方法,导致校验逻辑执行异常,还会产生重复保存的问题
  • Django默认规则限制:直接调用模型实例的save()方法不会自动触发clean校验,只有通过ModelForm、Admin后台等途径保存时才会自动执行clean逻辑
  • 潜在时区问题:使用原生datetime.now()生成时间,若项目开启时区配置USE_TZ = True会出现时间不兼容告警

修复步骤

  1. 修正clean方法的父类调用逻辑,将末尾的父类save调用改为clean调用
  2. 在重写的save方法开头主动调用full_clean(),触发自定义校验逻辑
  3. 替换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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 02:45:04