python - django annotate a function that returns the maximum of a field among all objects that has a feature -
suppose have model:
class student(models.model): class_name = models.charfield() mark = models.integerfield()
and want students have highest mark
in class. can student has highest mark
in classes mentioned in this post. want students have highest mark
in class, this:
student.objects.annotate( highest_mark_in_class=max( students.objects.filter(class_name=f('class_name')) .filter(mark=highest_mark_in_class) ) )
i can for
loop, large database for
loops rather slow. don't know if it's possible write such query in 1 line?
you have use 2 queries that:
import operator functools import reduce django.db.models import max, q best_marks = student.objects.values('class_name').annotate(mark=max('mark')) q_object = reduce(operator.or_, (q(**x) x in best_marks)) queryset = student.objects.filter(q_object)
first query gets list of best mark each class.
second query gets students mark , class matches 1 item of list.
note if call .annotate(best_mark=max('mark'))
instead of .annotate(mark=max('mark'))
, have work rename best_mark
mark
prior passing dictionnary q
object. while q(**x)
quite convenient.
Comments
Post a Comment