关于fetch的Django模型更新

时间:2016-08-08 09:20:24

标签: python django

我的模型有一个字段,如果它在一个日期范围内,则应该更改。

看起来像这样:

class Election(models.Model)
    start_date = models.DateTimeField(verbose_name = 'Start Date')
    end_date = models.DateTimeField(verbose_name = 'End date')
    active = models.BooleanField(default=False)

    def updateActive(self):
        now = timezone.now()
        if self.start_date < now and self.end_date > now:
            self.active=True
        else:
            self.active=False
        self.save()

现在,每当我查询此模型时,我都会从updateActive()拨打views.py

所以,我的问题是:每次获取updateActive()对象时,有没有办法调用Election?或者保持不断更新?

欢迎任何想法。

2 个答案:

答案 0 :(得分:1)

最好的方法是不要在模型中使用active字段。主要原因是,当一个值可以通过简单的计算生成时,它不应该存储在数据库中。第二个原因是BooleanField无法有效索引,涉及此字段的查询将很慢。因此,通过计算而不是执行字段,您不会丢失任何内容。最好的方法是添加如下自定义查询集:

class ElectionQuerySet(models.QuerySet):
    def is_active(self):
        return self.filter(start_date__lt=timezone.now()).filter(end_date__gt=timezone.now())

现在你的模型很简单。

类选举(models.Model):     start_date = models.DateTimeField(verbose_name =&#39;开始日期&#39;)     end_date = models.DateTimeField(verbose_name =&#39;结束日期&#39;)

objects = ElectionQuerySet.as_manager()

现在您的模型非常简单。

class Election(models.Model):
    start_date = models.DateTimeField(verbose_name = 'Start Date')
    end_date = models.DateTimeField(verbose_name = 'End date')

    objects = ElectionQuerySet.as_manager()

是的,这就是全部。每次获取对象时都无需更新数据库!您可以使用一种简单的方法来找出活动与否

Election.objects.is_active()

is_active的结果是一个查询集,您可以照常链接

Election.objects.is_active().filter(...)

如果您想检查模板中的选举是否有效,您可以这样做:

class Election(models.Model):
    def is_active()
         if self.start_date < now and self.end_date > now:
            return True

答案 1 :(得分:0)

您可以为模型编写自定义管理器。虽然您可以在查询本身中为实例设置活动属性,但从设计的角度来看它似乎并不正确(get方法不应该改变它正在查询的数据)。有一个活动属性是有意义的,因为您可能希望以后手动使某个实例无效。 您可以使用后台作业更新活动字段,这样您的经理就会像

一样
class ElectionManager(models.Manager):
def get_queryset(self):
    return super().get_queryset().filter(active=True)
class Election(models.Model):
    start_date = models.DateTimeField(verbose_name = 'Start Date')
    end_date = models.DateTimeField(verbose_name = 'End date')
    active = models.BooleanField(default=False)
    elections = ElectionManager()

这样Election.elections.all()只返回主动选举。 如果要通过类方法过滤掉查询,则可以使用列表推导或生成器在ElectionManager.get_queryset方法中获取所需的查询集。