Как сделать вычисления внутри django annotate?

Этот, когда я запускаю, выдает ошибку:

qs = UserLocation.objects.annotate(distance=0.5 - cos((F('lat')-lat1)*p)/2 + cos(lat1*p) * cos(F('lat')*p) * (1-cos((F('long')-lon1)*p))/2).all()

Ошибка, которую он выдает, следующая:

должно быть действительным числом, а не комбинированным выражением

Как я могу сделать этот расчет в виде аннотации

Попробуйте добавить ExpressionWrapper, как описано здесь: https://docs.djangoproject.com/en/3.2/ref/models/expressions/#using-f-with-annotations

qs = UserLocation.objects.annotate(distance=ExpressionWrapper(0.5 - cos((F('lat')-lat1)*p)/2 + cos(lat1*p) * cos(F('lat')*p) * (1-cos((F('long')-lon1)*p))/2).all(), output_field=FloatField())

Я мог пропустить некоторые ), потому что ваш расчет сложный, и я предположил, что результат является float

Я думаю, вам нужно использовать функцию Cos базы данных Django при нахождении косинуса значения, которое включает F() выражение.

Функция math.cos в Python, похоже, выдает ошибку must be real number при использовании с выражением F().

Для простого примера, это приводит к ошибке must be real number:

from math import cos

...

Vector.objects.annotate(x_cos=cos(F('x') + 1))

Но это, кажется, работает:

from django.db.models.functions import Cos

...

Vector.objects.annotate(x_cos=Cos(F('x') + 1))

Воспользовавшись вашим примером, я думаю, что вам нужно что-то вроде этого:

from math import cos
from django.db.models.functions import Cos

...

qs = UserLocation.objects.annotate(distance=0.5 - Cos((F('lat')-lat1)*p)/2 + cos(lat1*p) * Cos(F('lat')*p) * (1-Cos((F('long')-lon1)*p))/2)
Вернуться на верх