我正在尝试做一个非常简单的操作,但是我遇到了一个问题。 我有一个简单的模型:
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上进行过滤?
感谢。
答案 0 :(得分:3)
浮点数用Python表示的方式(Django的FloatField
映射到Python的float
,Django的DecimalField
映射到Python的decimal
;参见{{3 }})。
不同之处在于float
由于它们在您的计算机上的显示方式而不准确,decimal
类型旨在解决由此产生的一些问题(请查看here为它,他们解释得非常好。)
现在考虑到您尝试通过完全匹配获取float
的情况,您可以尝试两件事:
将value
上MyModel
的类型更改为docs(即value = models.DecimalField(max_digits=5, decimal_places=2, null=True)
)
如果您希望将类型保留为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']