Как сортировать Django QuerySet по внешнему значению?

У меня есть указатель, состоящий из пар (id, rank). Я хотел бы выполнить Django-запрос для идентификаторов, чтобы результирующий набор запросов упорядочивался по рангу (убыв).

Получение запроса легко:

rankings = {...}
result = MyModel.objects.filter(id__in=rankings.keys())

Кажется, ответ должен включать некоторую аннотацию, которую я могу использовать как часть order_by, но я не могу понять, как туда добраться.

EDIT: Я забыл упомянуть, что мне нужен результат как QuerySet, поскольку это часть конвейера API-интерфейса tastypie.

2 ответа

Единственный способ решить эту проблему - создать новую рейтинговую модель, связанную с первичной моделью. По каждому запросу я вставляю элементы ранжирования в эту модель, а затем могу выполнить order_by через отношение. (Использование аннотации для добавления ранга в школьные записи.)

class UserSchoolRanking(models.Model):
 user = models.ForeignKey(User)
 school = models.ForeignKey(School)
 rank = models.IntegerField()
bulk_user_school_rank = [UserSchoolRank(user=user, school_id=k, rank=v)
 for k, v in rankings.iteritems()]
UserSchoolRank.objects.bulk_create(bulk_user_school_rank)
schools = School.objects.filter(userschoolrank__user=user)\
 .annotate(rank=Min('userschoolrank__rank'))\
 .order_by('-userschoolrank__rank')


Что-то вроде этого?

rankings = { 1 : 2, 2: 1, ... } # i.e. { 'id' : 'ranking', ... }
objects = list(MyModel.objects.filter(id__in=rankings.keys()))
objects.sort(key=lambda obj: rankings[obj.id])

licensed under cc by-sa 3.0 with attribution.