Reputation: 272
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()
Create new field is wrong, but I cant do something like:
admin_amount.admin_order_field = 'admin_amount'
I found similar question but I encountered a problem with rewriting queryset() method(can't write something like qs.warehouse_set.all().annotate(models.Sum('amount'))
). Is there any way to adapt this solution for me or in my case, there is another solution?
Upvotes: 16
Views: 10548
Reputation: 15545
Using the code in the linked question (and the suggested edit), the bottom should do it for your example. The principle is to use annotate to add additional data from a sub-query to the returned QuerySet. In this case the Sum
of the amounts in warehouses.
Next you add a wrapper function amount_in_warehouses
to get this value out for each row, and tell the admin to show this for listing list_display = ('amount_in_warehouses',)
, and sort on it 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'
Upvotes: 23