如何通过计算过滤查询集?

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 提供数据库函数,如 COALESCELOWERSUM 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')

以上是关于如何通过计算过滤查询集?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django 中另一个查询集的结果过滤查询集?

构建请求 URL 以通过同一字段多次过滤 Django 查询集

如何按非字段值过滤 Django 查询集

Django admin 查询集通过外键向后关系过滤

通过 m2m 关系的直通表的值过滤 django 查询集

如何通过 Firebase 中的某些用户事件过滤 BigQuery 中的保留计算