Django admin: как сортировать столбец по пользовательскому методу

 class Item(models.Model):
     name = models.CharField(max_length=100, unique=True)

 def admin_amount(self):
     total = self.warehouse_set.all().aggregate(item=Sum('amount'))
     return total['item']

 class Warehouse(models.Model):
     name = models.CharField(max_length=100, unique=True)
     item = models.ForeignKey('Item', blank=True, null=True)
     amount = models.IntegerField()

создать новое поле неправильно, но я не могу сделать что-то вроде

 admin_amount.admin_order_field = 'admin_amount'

Я нашел аналогичный вопрос, но я столкнулся с проблемой перезаписи метода queryset() (не могу написать что-то вроде qs.warehouse_set.all().annotate(models.Sum('amount'))). Есть ли способ адаптировать это решение для меня или в моем случае, есть другое решение?

Ответ 1

Используя код в связанном вопросепредлагаемое редактирование), нижняя часть должна сделать это для вашего примера. Принцип заключается в использовании аннотата для добавления дополнительных данных из подзапроса в возвращаемый QuerySet. В этом случае Sum сумм на складах.

Затем вы добавляете функцию-обертку amount_in_warehouses, чтобы получить это значение для каждой строки, и сообщите администратору, чтобы показать это для перечисления list_display = ('amount_in_warehouses',) и сортировать по ней amount_in_warehouses.admin_order_field = 'amount_in_warehouses'.

class ItemAdmin(admin.ModelAdmin):
    list_display = ('amount_in_warehouses',)
    name = models.CharField(max_length=100, unique=True)

    def queryset(self, request):
        qs = super(ItemAdmin, self).queryset(request)
        qs = qs.annotate(models.Sum('warehouse__amount'))
        return qs

    def amount_in_warehouses(self, obj):
        return obj.warehouse__amount__sum
    amount_in_warehouses.admin_order_field = 'amount_in_warehouses'