我如何检查这个实例是从数据库启动的还是新对象

How can I check if this instance initing from database or it is new object

我有任务的 Django 模型。在我的网站中,任务可以重复,也可以不重复。所以我以这种方式覆盖 init 方法:


    def __init__(self, *args, **kwargs):
        """Init new Task
        :param period - timedelta object. How often should task be repeated
        :param repeated - if true task will be repeated
        :param end_date - datetime until which tasks will be repeated or it will be repeated for 10 years
        """
        if not self.from_database() # I don't now how to do it
            if kwargs.get("repeated"):
                period = kwargs["period"]
                end_date = kwargs["end_date"] or kwargs["date_time"] + TEN_YEARS
                base_task = self
                date = base_task.date_time + period
                with transaction.atomic():
                    while date <= end_date:
                        base_task.clone_task(date)
                        date += period
            try:
                del kwargs["repeated"]
                del kwargs["period"]
                del kwargs["end_date"]
            except KeyError:
                pass
        super().__init__(*args, **kwargs)

但是我有问题。我如何检查这个实例是从数据库初始化还是新对象。

首先,我不确定我是否会以这种方式设计您的任务创建。任务对象应该确定自己的范围,避免必须处理其他任务。也许,处理创建重复任务的选项的任务创建者可能更合适。这只是在不了解您的上下文的情况下提出的意见,但无需执行任何特殊操作即可避免您的问题。

也就是说,根据 Django 文档,您应该避免覆盖 init() 方法。它提出了另外两种方法。其中之一涉及覆盖管理器。

https://docs.djangoproject.com/en/3.2/ref/models/instances/

它让你从你的对象内部封装一些逻辑,并且从 oop 的角度来看,这是有争议的,但可以理解。然而,在django的做事方式中,你应该将这种逻辑封装在一个专门的管理器中。

我使用这种方式在我的许多实体中维护 created_at、updated_at、deleted_at 和 is_deleted 等字段,并且工作正常。

我不建议从对象创建内部创建对象。如果你想这样做,请确保,你的 clone_task 方法不包含 repeated 参数,否则每个重复的任务都会创建许多重复的任务,你最终会得到很多重复项。