如何通过计算过滤查询集?
Posted
技术标签:
【中文标题】如何通过计算过滤查询集?【英文标题】:How filter queryset with a calculation? 【发布时间】:2018-10-29 19:19:21 【问题描述】:我有一个类似的模型
class House:
x = IntegerField()
y = IntegerField()
我想使用以下计算返回距离某个位置距离更小的房屋:
abs(house.x - myPos.x) + abs(house.y - myPos.y) < distance
但我不知道如何制作该过滤器,因为 filter() 仅与模型的字段进行比较。我想做类似的事情:
House.objects.filter(abs(x - myPos.x) + abs(y - myPos.y) < distance)
【问题讨论】:
【参考方案1】:这个问题的解决方法可以分两步解决:
-
注释
abs(x - myPos.x) + abs(y - myPos.y)
表达式
将带注释的表达式与distance
值进行比较
为了注释表达式,Django ORM 支持 func expressions 提供数据库函数,如 COALESCE、LOWER、SUM、 ABS 等等。
对于您的示例,您可以使用以下查询:
from django.db.models import Func, F
House.objects.annotate(abs_calculation=Func(F('x') - myPos.x, function='ABS') + Func(F('y') - myPos.y, function='ABS')).filter(abs_calculation__lt=distance)
【讨论】:
完美!我看到了所有这些东西,但我无法将它们放在一起。谢谢! 您好,我还有一个问题,以防您知道。如果我的模型具有多对多关系(例如 x 和 y 位于对象位置),我可以使用 F() 访问它们吗?例如像 F("location.x")? (我试过了,还是不行) 好的,我发现我可以将 F("location__x") 类型的符号用于其他多对多关系,但在我的情况下,我意识到我有一个 PointField,所以这就是它不起作用的原因。 你不需要与 Location 多对多的关系,因为一所房子只能在一个位置上,一个房子不能有多个位置。您基本上需要与 Location 的 ForeignKey 关系,在这种情况下,我会尝试使用 F('location__x')以上是关于如何通过计算过滤查询集?的主要内容,如果未能解决你的问题,请参考以下文章