繁体   English   中英

获取相关型号日期字段的最小值(django)

[英]Get minimum of related model date field (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)

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

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

那么模板应该 - 严格来说 - 包含业务逻辑 它应该包含渲染逻辑 因此,应规定什么应该怎么可见,没有什么应该是可见的。 所以它并不真正属于模板层,只在模型层中。

您可以获得报告的最小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']

这将忽略 Sourcedatereported设置为None (因此,如果有多个源,则需要最小的datereported不是None )。 如果没有Sourcedatereported不等于None ,或不相关的Source s的一切,它将返回None然而,由于空集的最小值被认为是NULL (在SQL或None在Python / Django的) 。

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

{{ some_incident.first_reporteddate }}

如果你想要整个对象,可以使用self.source_set.order_by('datereported').first() ,它将为你提供最早的相关Source实例。 但这会对性能产生(相当小)影响(需要更长时间)。 在这种情况下,Django将首先将所有列提取到内存中。 如果你只需要一个列,这将导致你做了一些无用的序列化(在数据库端)和反序列化(在Python端)。

您可以使用model的属性:

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 }}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM