[Django]-Get minimum of related model date field (django)

4πŸ‘

βœ…

Is this best done in the model, or in the template?

Well a template should – strictly speaking – not contain business logic. It should contain render logic. It should thus specify how something should be visible, not what should be visible. So it dos not really belong in the template layer, only in the model layer.

You can obtain the smallest datereported with:

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']

This will ignore Sources with datereported set to None (so if there are multiple sources, it takes the smallest datereported that is not None). If there are no Source with a datereported not equal to None, or no related Sources at all, it will return None however, since the minimum of an empty set is considered to be NULL (in SQL, or None in Python/Django).

You can then use this in the template like:

{{ some_incident.first_reporteddate }}

In case you want the entire object, you can use self.source_set.order_by('datereported').first() which will give you the earliest related Source instance. But this will have a (quite) small impact on performance (it will take a bit longer). In that case Django will fetch all columns into memory first. If you thus only need one column, this will result in the fact that you did some useless serialization (at the database end) and deserialization (at the Python end).

3πŸ‘

You can use model’s property for this:

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

In template or in any other part of code you can use first_datereported as normal model’s field:

{{ incident_instance.first_datereported }}

Leave a comment