【问题标题】:Flagging a django model instance during save for later processing在保存期间标记 django 模型实例以供以后处理
【发布时间】:2021-10-16 23:33:25
【问题描述】:

我在使用标志来标记模型实例以供将来处理时遇到了问题。我有一堂课:

class MyModel(models.Model):
    processed = models.BooleanField(default=False)
    changed = models.DateTimeField(auto_now=True)
    # More fields.

    def save(self):
        self.processed = False
        super().save(*args, **kwargs)

然后我有一个管理命令:

class Command(BaseCommand):

    def handle(self, *args: Any, **kwargs: Any) -> None:
        models = MyModel.objects.filter(processed=False).order_by("changed")[:200]
        for model in models:
            # Do some processing
            model.processed = True
            model.save()

现在,很明显,当模型被保存时,它只是将实例重新标记为未处理。

我是 django 新手,所以我对模型生命周期和可用方法的了解非常有限。我一直在阅读文档,到目前为止还没有找到任何解决方案。

有什么想法可以解决这个问题吗?

【问题讨论】:

    标签: django django-models django-model-field


    【解决方案1】:

    解决这个问题的最好方法可能是添加一个参数来忽略标记:

    class MyModel(models.Model):
        processed = models.BooleanField(default=False)
        changed = models.DateTimeField(auto_now=True)
        # More fields.
    
        def save(self, *args, unset_processed=True, **kwargs):
            if unset_processed:
                self.processed = False
            super().save(*args, **kwargs)

    然后在您的基本命令中,我们可以使用:

    class Command(BaseCommand):
    
        def handle(self, *args: Any, **kwargs: Any) -> None:
            models = MyModel.objects.filter(processed=False).order_by("changed")[:200]
            for model in models:
                # Do some processing
                model.processed = True
                model.save(unset_processed=False)

    但是请注意,批量创建、更新等将规避在模型上调用.save(…)。因此,例如,如果您使用:

    MyModel.objects.filter(pk__in=[1,4,2,5])<strong>.update(</strong>some_field=some_value<strong>)</strong>

    例如不会调用.save(…) 方法。 documentation on .update(…) [Django-doc] 举例说明:

    最后,意识到update() 在 SQL 级别进行了更新,并且, 因此,不会在您的模型上调用任何 save() 方法,也不会 它发出pre_savepost_save 信号

    (…)

    如果您想为具有自定义的模型更新一堆记录 save() 方法,循环它们并调用save(),像这样:

    for e in Entry.objects.filter(pub_date__year=2010):
        e.comments_on = False
        e.save()
    

    【讨论】:

      猜你喜欢
      • 2012-12-12
      • 2019-06-24
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 2016-10-13
      • 1970-01-01
      相关资源
      最近更新 更多