views:

27

answers:

1

Hi, I have a model which looks like this:

class MyModel(models.Model)
    value = models.DecimalField()
    date = models.DatetimeField()

I'm doing this request:

MyModel.objects.aggregate(Min("value"))

and I'm getting the expected result:

{"mymodel__min": the_actual_minimum_value}

However, I can't figure out a way to get at the same time the minimum value AND the associated date (the date at which the minimum value occured).

Does the Django ORM allow this, or do I have to use raw SQL ?

+2  A: 

What you want to do is annotate the query, so that you get back your usual results but also have some data added to the result. So:

MyModel.objects.annotate(Min("value"))

Will return the normal result with mymodel__min as an additional value

In reply to your comment, I think this is what you are looking for? This will return the dates with their corresponding Min values.

MyModel.objects.values('date').annotate(Min("value"))

Edit: In further reply to your comment in that you want the lowest valued entry but also want the additional date field within your result, you could do something like so:

MyModel.objects.values('date').annotate(min_value=Min('value')).order_by('min_value')[0] 

This will get the resulting dict you are asking for by ordering the results and then simply taking the first index which will always be the lowest value. See more

Bartek
Correct me if I am wrong, but:with annotate, the queryset will return all my model instances, each with the 'mymodel__min' attribute.It will not tell me at which date the minimum occured (except if I manually compare, for each price returned, the value to the minimum value and pick the date if they match).
Jeremy
You are correct. Sorry, I didn't realize that was also part of your question. I adjusted my question so you could group by dates which seems to be what you want, yes?
Bartek
Using 'annotate' returns all the MyModel instances. I'm only interested in the instance whose value is the minimum value, and get its date.With your new request, I'm getting a list of dicts, each having a different date, and a different minimum (which actually corresponds to the value and date in each model instance).
Jeremy
Sorry! There is no way to do this using `aggregate` within Django as it's simply built to return the dict of results that you ask for. However, you could get what you want with some ordering and then just grabbing the first entry. e.g.:MyModel.objects.values('date').annotate(min_value=Min('value')).order_by('min_value')[0]Hope that gets what you need!
Bartek
Using order_by actually solves the problem, I just thought there was a "more elegant" way of solving this.Anyway, it works and I don't have to write SQL. Hooray !
Jeremy