I am trying to take a queryset and annotate it so that the value of the new field is the result of a function that requires the object being annotated. In this case I am taking a queryset of cars and annotating it with the distance of the car which is calculated by a function.
The main issue I am having is getting the annotations to be unique to each car rather than a bulk annotation, I have tried most of the approaches mentioned elsewhere on here but none seem to be working.
The closest I have come so far is by using an approach using Unions, this got the annotations in, however my next step is to order this Queryset so I need to have the ability to do that without losing the annotation.
For context: car is a Car object, distances is a dictionary of distances. Unannotated is initially set to a queryset of cars which may already have annotation applied from a previous function.
The Union solution I found is:
for car in unannotated:
annotated = unannotated.filter(id=car.id).annotate(distance=Value(get_distance_of_car_from_distances(distances, car)))
clean = clean.union(annotated)
However as stated previously, this caused issues with the ordering step further on.
I have also tried the following solution
for car in unannotated:
unannotated = unannotated.filter(id=car.id).annotate(distance=Value(get_distance_of_car_from_distances(distances, car)))
However as soon as I try to view the new field I get AttributeError: 'NoneType' object has no attribute 'distance'
I have also tried this solution:
unannotated = unannotated.annotate(distance=Value(0))
for car in unannotated:
print(car.distance)
car.distance = get_distance_of_car_from_distances(distances, car)
car.save()
However this does not appear to do anything as all distances are still set to 0.
The next step in my program is to order the Queryset so a Union method is probably not the best way to go unless there's a way around this and I would like to keep any existing annotation if possible.
Sorry if this is long winded, I figured more is better.