Saqib Ali
Saqib Ali

Reputation: 12545

How to get the Django model with maximum field value?

I have a Django class that looks like this:

class MyModel(models.Model):
    my_integer = models.IntegerField(default=-1)
    created_ts = models.DateTimeField(default=datetime.utcnow, editable=False)

How can I get the instance of the model (not just the value of the field) that has the latest created_ts for a given value of my_integer? I thought the line below using annotate would work, However that retuned to me all 3 instances of MyModel that had my_integer==77 instead of the single value I was expecting. And weirdly, each of these 3 instances has last_created set to its own created_ts instead of the max of all matching instances.

>>> len(MyModel.objects.filter(my_integer=77))
3

>>> from django.db.models import Max, F
>>> x = MyModel.objects.filter(my_integer=77).annotate(last_created=Max('created_ts')).filter(created_ts=F('last_created'))
>>> len(x)
3

>>> print x[0].my_integer, x[0].created_ts, x[0].last_created
77 2015-09-07 07:46:27.343869 2015-09-07 07:46:27.343869

>>> print x[1].my_integer, x[1].created_ts, x[1].last_created
77 2015-09-12 07:46:27.343869 2015-09-12 07:46:27.343869

>>> print x[2].my_integer, x[2].created_ts, x[2].last_created
77 2015-09-13 07:46:27.343869 2015-09-13 07:46:27.343869

Upvotes: 0

Views: 2577

Answers (1)

Rohan
Rohan

Reputation: 53326

You can use .latest() on the queryset. So you can get the object as

obj = MyModel.objects.filter(my_integer=77).latest('created_ts')

You can also use .order_by() and .first()

obj = obj = MyModel.objects.filter(my_integer=77).order_by('-created_ts').first()

Upvotes: 2

Related Questions