Reputation: 125
This one when I run generates error:
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()
The error it generates is this one:
must be real number, not CombinedExpression
How can I make that calculation as an annotation
Upvotes: 2
Views: 1806
Reputation: 522
I think you need to use Django's Cos database function when finding the cosine of a value which involves an F()
expression.
Python's math.cos
function seems to produce the must be real number error when used with an F()
expression.
To take a simple example, this produces the must be real number error:
from math import cos
...
Vector.objects.annotate(x_cos=cos(F('x') + 1))
But this seems to work:
from django.db.models.functions import Cos
...
Vector.objects.annotate(x_cos=Cos(F('x') + 1))
So to take your example, I think you'll want something like this:
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)
Upvotes: 0
Reputation: 1632
Try adding ExpressionWrapper as described here: 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())
I might missed some )
because your calculation is complicated and I assumed that result is a float
Upvotes: 2