epord
epord

Reputation: 471

How filter queryset with a calculation?

I have a model similar to

class House:
    x = IntegerField()
    y = IntegerField()

I want to return the houses that are at a smaller distance that distance from some position using the following calculation:

abs(house.x - myPos.x) + abs(house.y - myPos.y) < distance

But I don't know how to make that filter since filter() only compares with a model's field. I would like to do something like:

House.objects.filter(abs(x - myPos.x) + abs(y - myPos.y) < distance)

Upvotes: 6

Views: 2349

Answers (1)

T.Tokic
T.Tokic

Reputation: 1254

The solution for this problem can be resolved in 2 steps:

  1. Annotate abs(x - myPos.x) + abs(y - myPos.y) expression
  2. Compare annotated expression with distance value

In order to annotate the expression Django ORM supports func expressions who provide database functions like COALESCE, LOWER, SUM, ABS and many other.

For your example you can use this query:

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)

Upvotes: 7

Related Questions