最少获取相关模型日期字段(django)

时间:2018-07-01 17:06:02

标签: python django

我有以下两个课程:

class Incident(models.Model):
    iid = models.IntegerField(primary_key=True)
    person = models.ForeignKey('Person', on_delete=models.SET_NULL, null=True)


class Source(models.Model):

    sid = models.IntegerField(primary_key=True)
    incident = models.ForeignKey('Incident', on_delete=models.SET_NULL, null=True)
    url = models.TextField(validators=[URLValidator()])
    datereported = models.DateField(null=True, blank=True)

我想在事件中创建一个字段,该字段将提取相关来源的最小日期报告。这是最好在模型中还是在模板中完成?不确定什么是最佳做法,或者在这种情况下如何执行。

2 个答案:

答案 0 :(得分:4)

  

这是最好在模型中还是在模板中完成?

严格来说,模板应该包含业务逻辑。它应包含渲染逻辑。因此,它应指定如何可见,而不是什么可见。因此它并不真正属于模板层,而仅属于模型层。

您可以使用以下方法获得最小的datereported

from django.db.models import Min

class Incident(models.Model):
    iid = models.IntegerField(primary_key=True)
    person = models.ForeignKey('Person', on_delete=models.SET_NULL, null=True)

    @property
    def first_reporteddate(self):
        return self.source_set.aggregate(first=Min('datereported'))['first']

这将忽略 Source,其中datereported设置为None(因此,如果有多个来源,则占用最小的datereported不是None)。如果没有Source不等于datereported的{​​{1}},或者根本没有相关的None,则它将返回Source,因为最小值空集的值被认为是None(在SQL中,或在Python / Django中为NULL)。

然后您可以在模板中使用它,例如:

None

如果需要整个对象,可以使用{{ some_incident.first_reporteddate }},它会为您提供与最早相关的self.source_set.order_by('datereported').first()实例。但这对性能的影响很小(会花费更长的时间)。在这种情况下,Django将首先将 all 列提取到内存中。因此,如果您只需要 one 列,则将导致您进行了无用序列化(在数据库端)和反序列化(在Python端)。 / p>

答案 1 :(得分:3)

您可以为此使用模型的属性:

class Incident(models.Model):
    iid = models.IntegerField(primary_key=True)
    person = models.ForeignKey('Person', on_delete=models.SET_NULL, null=True)

    @property
    def first_datereported(self):
        first_source = self.source_set.order_by('datereported').first()
        if first_source:
            return first_source.datereported

在模板或代码的任何其他部分,您可以将first_datereported用作普通模型的字段:

{{ incident_instance.first_datereported }}