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

在Django中如何最优建模孩子的当前圣诞愿望清单?

最优实现方案

直接在你最初的WishList模型基础上优化,解决所有痛点的同时满足需求:

调整后的模型代码

from django.db import models

class Kid(models.Model):
    name = models.CharField(max_length=255)  # Django的CharField必须指定max_length

    @property
    def current_wishlist(self):
        # 快捷获取当前清单,不用重复写查询逻辑
        return self.wishlist_set.filter(current=True).first()

class Gift(models.Model):
    name = models.CharField(max_length=255)

class WishList(models.Model):
    date_received = models.DateTimeField(auto_now_add=True)  # 自动记录创建时间,无需手动传入
    kid = models.ForeignKey(Kid, on_delete=models.CASCADE)
    current = models.BooleanField(default=False, db_index=True)  # 加索引提升查询效率
    gifts = models.ManyToManyField(Gift)  # 关联愿望清单与对应的礼物,补全你原来缺失的关联

    class Meta:
        constraints = [
            # 数据库层面强制每个孩子最多只有一个"当前"清单
            models.UniqueConstraint(
                fields=['kid'],
                condition=models.Q(current=True),
                name='unique_current_wishlist_per_kid'
            )
        ]

核心痛点解决

  1. 查询效率问题:给current字段添加db_index=True,数据库会为该字段建立索引,99%查询当前清单的场景下,数据库直接走索引检索,效率完全有保障。
  2. 多当前清单问题:通过UniqueConstraint设置条件唯一约束——仅当current=True时,每个kid对应的记录是唯一的。数据库会直接拦截重复创建操作,无需你编写额外验证代码,从根源避免问题。

额外需求满足

  • 切换旧清单为当前:只需把原当前清单的current设为False,再将目标旧清单的current设为True即可,无需复制清单或修改日期,操作简单且不混淆。
  • 归档历史清单:所有current=False的记录自动成为历史归档,直接通过wishlist_set.filter(current=False)就能获取所有历史清单。

其他方案的弊端

  • 取最新清单的方案:无法满足切换旧清单的需求,直接排除。
  • 拆分current_wishlist和archived_wishlists的方案:冗余度极高,比如将归档清单设为当前时,需要手动从多对多关系中移除并维护一对一关联,极易出现bug,完全没必要。

内容的提问来源于stack exchange,提问作者aimlesslegs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:05:27