Django queryset - 是不是可以在FloatField上过滤?

时间:2014-09-24 12:19:53

标签: python django django-queryset

我正在尝试做一个非常简单的操作,但是我遇到了一个问题。 我有一个简单的模型:

class MyModel(models.Model):
    date = models.DateTimeField(null=False)
    value = models.FloatField(null=True)
    interval = models.IntegerField(null=True)

我的目标是获得具有最大价值的MyModel对象。

#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)

此代码引发错误:“匹配查询不存在”... 我试图硬编码一个值(存在),我有同样的错误。

我做错了吗?是否可以在FloatField上进行过滤?

感谢。

3 个答案:

答案 0 :(得分:3)

浮点数用Python表示的方式(Django的FloatField映射到Python的float,Django的DecimalField映射到Python的decimal;参见{{3 }})。

不同之处在于float由于它们在您的计算机上的显示方式而不准确,decimal类型旨在解决由此产生的一些问题(请查看here为它,他们解释得非常好。)

现在考虑到您尝试通过完全匹配获取float的情况,您可以尝试两件事:

  1. valueMyModel的类型更改为docs(即value = models.DecimalField(max_digits=5, decimal_places=2, null=True)

  2. 如果您希望将类型保留为FloatField,则可以尝试查询一系列值,但最终可能会产生超过1个结果(因此MyModel.objects.get()可能会抛出一个异常,抱怨查询返回了多于1个结果):MyModel.objects.filter(value__range=(1.23, 1.24))MyModel.objects.filter(value__gte=1.23, value__lt=1.24)

答案 1 :(得分:2)

获取具有最大值的对象的更简单方法是订购它并采取第一个:

value = MyModel.objects.filter(date__gte='2014-05-01', date__lte='2014-05-31').order_by('-value')[0]

这样做的好处是它只是一个查询而不是2,并且不会产生昂贵的聚合。

答案 2 :(得分:1)

date字段DateTimeField,但代码正在传递字符串。改为指定datetime.date

import datetime

...

value = MyModel.objects.filter(
    date__gte=datetime.date(2014, 5, 1),
    date__lte=datetime.date(2014, 5, 31)
).aggregate(Max('value'))['value__max']