Saturnix
Saturnix

Reputation: 10564

Compare annotations in Django ORM filter

I'm trying to translate this query into a Django ORM call.

Model:

class model(models.Model):
    member = CharField()
    pos = IntField()

Query

SELECT member
FROM model
GROUP BY member
HAVING MIN(pos) = MAX(pos);

What I'm trying:

q = model.objects.all()

q.annotate(min=Min('pos'), max=Max('pos')).values('member','pos').filter(min=max)

This almost works, if it wasn't for the last call to .filter(min=max). Apparently, I'm not allowed to compare 2 annotations this way.

TypeError: int() argument must be a string, a bytes-like object or a number, not 'builtin_function_or_method'

Is this possible in any other way?

EDIT: no, this doesn't almost works. It's completely wrong...

Upvotes: 0

Views: 661

Answers (1)

Tsang-Yi Shen
Tsang-Yi Shen

Reputation: 542

I think this is what you are looking for:

from django.db.models import F, Min, Max

q = model.objects.values('member') \
    .annotate(min_pos=Min('pos'), max_pos=Max('pos')) \
    .filter(min_pos=F('max_pos')) \
    .values('member')

Here I use min_pos and max_pos instead of min, max since they are the built-in functions of python.

Upvotes: 4

Related Questions