I’m trying to do a very simple operation but I get an issue. I have a simple model :
class MyModel(models.Model):
date = models.DateTimeField(null=False)
value = models.FloatField(null=True)
interval = models.IntegerField(null=True)
My goal is to get the MyModel object with the biggest value.
#Get the value
value = MyModel.objects.filter(date__gte=’2014-05-01’, date__lte=’2014-05-31’).aggregate(Max(‘value’))[‘value__max’]
# Get the object corresponding to the max value
my_object = MyModel.objects.get(value=value)
This code raise me an error : “matching query does not exist” … I tried to hardcode a value (that exists), I have the same error.
Am I doing something wrong ? Isn’t it possible to filter on a FloatField ?
Thanks.
date
fieldDateTimeField
, but the code is passing strings. Specifydatetime.date
instead:An easier way to get the object with the largest value would be to order it and take the first:
That has the advantage that it's a single query rather than 2, and doesn't incur an expensive aggregation.
It is with the way floating point numbers are represented in Python (Django's
FloatField
maps to Python'sfloat
and Django'sDecimalField
maps to Python'sdecimal
; see here).The difference is that
float
s are not precise because of the way they are represented on your computer, thedecimal
type aims to remedy some of these issues that arise through that (have a look at the docs for it, they explain that very well).Now given your case of trying to fetch a
float
via an exact match you can try 2 things:Change the type of
value
onMyModel
to aDecimalField
(i.e.value = models.DecimalField(max_digits=5, decimal_places=2, null=True)
)If you want to keep the type as a
FloatField
you can try to query a range of values, however you might end up with more than 1 result (soMyModel.objects.get()
might throw an exception, complaining that the query returned more than 1 result):MyModel.objects.filter(value__range=(1.23, 1.24))
orMyModel.objects.filter(value__gte=1.23, value__lt=1.24)