Django中基于关联规则限制MyModel对象定时重复创建
Django模型创建限制逻辑修复
原代码的核心问题
- 规则查询错误:
rule_model = RuleModel()创建的是空实例,遍历它不会获取任何实际的场馆规则数据 - 范围检查错误:查询
MyModel时未限定当前关联的Venue,导致检查范围覆盖了所有场馆的记录 - 逻辑分支缺失:没有处理无规则时的默认保存逻辑,多规则场景下执行流程混乱
- 无错误提示:保存失败时静默处理,无法排查问题
修复后的完整代码
首先确保导入必要模块:
from django.core.exceptions import ValidationError import datetime
修改后的模型代码:
class Venue(models.Model): name = models.CharField(verbose_name="Name", max_length=100, blank=True) class RuleModel(models.Model): venue = models.ForeignKey(Venue, null=True, blank=True, on_delete=models.CASCADE) points = models.IntegerField(verbose_name="loylaty_points_rule", null=True, blank=True) timestamp = models.DateTimeField(auto_now_add=True) timeframe = models.IntegerField(verbose_name='timeframe during which more points cannot be reclaimed', null=True, blank=True) class MyModel(models.Model): user = models.ForeignKey(UserProfile, blank=True, null=True, on_delete=models.CASCADE) venue = models.ForeignKey(Venue, blank=True, null=True, on_delete=models.CASCADE) add_points = models.DecimalField(name='add_points', null=True, blank=True, default=0, decimal_places=2, max_digits=50) qr_code_venue = models.ImageField(upload_to='qr_codes_venue', blank=True) timestamp = models.DateTimeField(auto_now_add=True, null=True, blank=True) def save(self, *args, **kwargs): # 仅当关联场馆时才执行规则检查 if self.venue: # 获取当前场馆下配置了有效时长的规则,按创建时间取最新的 valid_rules = RuleModel.objects.filter( venue=self.venue, timeframe__isnull=False ).order_by('-timestamp') if valid_rules.exists(): active_rule = valid_rules.first() # 计算时间阈值 time_threshold = datetime.datetime.now() - datetime.timedelta(days=active_rule.timeframe) # 检查当前场馆下是否有阈值内的记录 has_recent_record = MyModel.objects.filter( venue=self.venue, timestamp__gte=time_threshold ).exists() if has_recent_record: raise ValidationError(f"该场馆【{self.venue.name}】{active_rule.timeframe}天内已有记录,无法重复创建") # 规则检查通过或无规则限制,执行保存 super().save(*args, **kwargs)
关键优化点
- 精准规则匹配:仅查询当前
MyModel关联场馆的有效规则,避免无关规则干扰 - 高效存在性检查:用
exists()替代get(),无需获取完整对象,性能更优且避免异常处理冗余 - 明确错误反馈:抛出
ValidationError,调用方可以捕获并返回友好提示,而非静默失败 - 灵活规则选择:默认取最新创建的规则,可根据业务需求调整规则筛选逻辑(如取特定优先级规则)
内容的提问来源于stack exchange,提问作者PhilM
相关产品推荐
相关产品推荐

