首页 > 解决方案 > 获取相关模型日期字段的最小值(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。这最好在模型中还是在模板中完成?不确定最佳实践是什么,或者在这种情况下如何执行。

标签: pythondjango

解决方案


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

一个模板应该——严格来说——包含业务逻辑。它应该包含渲染逻辑。因此,它应该指定某些东西应该如何可见,而不是什么应该可见。所以它并不真正属于模板层,只属于模型层。

您可以通过以下方式获得最小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的 s (因此,如果有多个来源,则采用最小的不是)。如果 no不等于,或者根本没有相关的 s,那么它将返回,因为空集的最小值被认为是(在 SQL 或Python/Django 中)。datereportedNonedatereportedNoneSourcedatereportedNoneSourceNoneNULLNone

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

{{ some_incident.first_reporteddate }}

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


推荐阅读