2016-08-08 74 views
1

我的模型有一个字段,如果它处于日期范围内,则该字段应该更改。取回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

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

任何想法是值得欢迎的。

+3

它会是一个选项,根本不存储它,只是在需要时计算它吗? – RemcoGerlich

+0

这就是我一直在做的事。我只是想知道是否有一种方法来实现这一点。 – Pabs

+0

不确定自动更新,但逻辑看起来不正确:'如果self.start_date>现在和self.end_date end_date'这可能不是你想要的。尝试'self.active = start_date mhawke

回答

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 = '开始日期') END_DATE = models.DateTimeField(verbose_name = '结束日期')​​

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结果是一个QuerySet,你可以链接它像往常一样

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

,如果你想检查是否选举在你可以做的模板中是活跃的:

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

这在模型中效果很好,但我在如何在HTML模板中调用自定义管理器时有点失落。 – Pabs

+0

模板在原始问题中未提及。您无法从模板(自定义或默认)访问管理器。 – e4c5

+0

我注意到了。我只是通过不同的查询集到我的HTML和它的工作。感谢您的巡演答案。 – Pabs

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方法中获取所需的查询集。

+0

虽然有趣,不完全是我的意图,因为我有一个观点,显示了所有通过,正在进行和即将举行的选举表。这就是为什么我想要更新主动标签的原因。 – Pabs