【问题标题】: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)

【问题讨论】:

    标签: python django django-queryset django-filter


    【解决方案1】:

    这个问题的解决方法可以分两步解决:

    1. 注释abs(x - myPos.x) + abs(y - myPos.y)表达式
    2. 将带注释的表达式与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')
    猜你喜欢
    • 2013-06-11
    • 2016-02-01
    • 1970-01-01
    • 2019-06-18
    • 2021-05-30
    • 2021-02-19
    • 2014-01-08
    • 2023-02-26
    • 2020-09-15
    相关资源
    最近更新 更多