#python #django #django-queryset
#python #django #django-набор запросов
Вопрос:
Я пытаюсь реализовать qs.sort_by
операцию, но я не уверен, как это сделать.
Учитывая следующие модели
class Group(models.Model):
name = models.CharField(max_length=300)
( ... )
class Budget(models.Model):
( ... )
amount = models.DecimalField(
decimal_places=2,
max_digits=8,
)
group = models.ForeignKey(
Group,
related_name="budgets",
on_delete=models.CASCADE,
)
Где для каждого Group
0
> 5
из них назначены бюджеты или
Я пытаюсь отсортировать Group.objects.all()
набор запросов по их количеству last
(например, по самому последнему назначению) Budget
.
Я знаю, что если бы это было OneToOne
, я мог бы сделать что-то вроде следующего:
Group.objects.all().order_by('budget__amount')
С ForeignKey
отношениями я надеялся, что смогу сделать что-то вроде
Group.objects.all().order_by('budgets__last__amount')
Но, увы, это недопустимая операция, но я не уверен, как поступить иначе.
Кто-нибудь знает, как выполнить эту операцию сортировки? (если это действительно возможно)
Комментарии:
1. Вам придется использовать аннотацию , но у меня сейчас нет времени, чтобы просто ввести точный ответ для вас. Что-то вроде
Group.objects.annotate(last_amount=Min('budget__amount').order_by('last_amount')
.2. Что определяет, что является последним? Есть ли у вас поле метки времени в бюджете?
3. На данный момент я использую значение первичного ключа по умолчанию. Все запросы используют логику Group.budget.last()
4. @Jasper У вас есть способ вручную получить каждый
budgets__last__amount
из них?
Ответ №1:
Это должно сделать это:
latest = Budget.objects.filter(group=OuterRef('pk')).order_by('-pk')
Group.objects.annotate(
latest_budget=Subquery(
latest.values('amount')[:1]
)
).order_by('latest_budget')
Ответ №2:
Вы можете попробовать использовать sorted
с пользовательским ключом:
sorted(Group.objects.all(), key=lambda x: x.last__budget__amount)
Возможно .last__budget__amount
, это недопустимый метод, но вы поняли идею.
Комментарии:
1. Спасибо за ваш ответ! Увы, это приводит к
object has no attribute 'last__budget__amount'
. Использованиеlast__
, похоже, не является допустимым методом в этом контексте.2. @Jasper я знаю. Каким бы ни был ручной метод получения каждой последней суммы бюджета, вы можете применить это к
x
.3. Не делайте в python того, что вы можете сделать в базе данных.