gpt4 book ai didi

django - 如何对 Django 'F' 类型进行算术运算?

转载 作者:行者123 更新时间:2023-12-04 04:06:05 25 4
gpt4 key购买 nike

我有一个事件模型,为了简单起见,它只有一个经纬度 FloatField()。

从 python 原生的“geopy.distance”库中,您可以像这样获取两个坐标之间的距离:

from geopy.distance import distance
home = (33.28473, -117.20384)
event = (33.829384, -117.38932)
distance = distance(home, event).miles #returns a float

在我的应用程序上下文中,我需要按位置对所有事件进行排序。我尝试了标准的 Django 注释语法:

Event.objects.all().annotate(distance=distance( (F('lat'),F('lon')), home ).miles).order_by('distance')

但是我从 geopy 库中得到以下错误:

TypeError: float() argument must be a string or a number, not 'F'

奇怪的是,这有效:

>>> def foo(x):
return x * 2
>>> Event.objects.all().annotate(cutomField=foo(F('field')))

似乎您可以使用 F 类型进行算术运算,但 geopy 似乎不知道这一点。

有没有办法将 F 类型转换为 float 以便 geopy 可以处理该字段?

最佳答案

Django 支持查询表达式的否定、加法、减法、乘法、除法、模运算和幂运算符,使用 Python 常量、变量甚至其他表达式。

F() 对象表示模型字段或注释列的值。这使得引用模型字段值并使用它们执行数据库操作成为可能,而无需实际将它们从数据库中拉出到 Python 内存中。

相反,Django 使用 F() 对象生成一个 SQL 表达式,该表达式描述了数据库级别所需的操作。

以上详情来自django官方documentation link

例如 1。

def foo(x):
return x*2

qs = MyModel.objects.filter().annotate(res=foo(F('colN')))
print(qs.query)

输出:

SELECT col1, col2, ("model_table"."colN"* 2) AS "res"FROM "model_table"

例如2(考虑另一个功能)。

def foo_power(x):
return x**2 ## POWER of 2

qs = MyModel.objects.filter().annotate(res=foo_power(F('colN')))
print(qs.query)

输出:SELECT col1, col2, (POWER("music_movie"."title",2)) AS "res"FROM "model_table"

这表明计算发生在数据库端:

对于 geopy.distance 情况:

对于自定义集合计算,我们需要在 django 内置数据库函数的帮助下编写自己的 Func。可以关注https://docs.djangoproject.com/en/3.0/ref/models/expressions/#func-expressions

有没有办法将 F 类型转换为 float 以便 geopy 可以处理该字段?

不,您不能键入 cast F() 即 'django.db.models.expressions.F'> 以 float 。

因为:

def foo_power(x):
print(type(x), x)
return x**2 ## POWER of 2

qs = MyModel.objects.filter().annotate(res=foo_power(F('colN')))

输出: F(标题)

关于django - 如何对 Django 'F' 类型进行算术运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62505949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com