Django admin:如何通过自定义方法对列进行排序

时间:2023-02-01 20:18:23
 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?

我发现了类似的问题,但我遇到了重写queryset()方法的问题(不能写像qs.warehouse_set.all()。annotate(models.Sum('amount')))。有没有办法为我或我的情况调整这个解决方案,还有另一种解决方案吗?

1 个解决方案

#1


17  

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.

使用链接问题中的代码(以及建议的编辑),底部应该为您的示例执行此操作。原则是使用annotate将子查询中的其他数据添加到返回的QuerySet。在这种情况下,仓库中的金额总和。

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'.

接下来,添加一个包装函数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'

#1


17  

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.

使用链接问题中的代码(以及建议的编辑),底部应该为您的示例执行此操作。原则是使用annotate将子查询中的其他数据添加到返回的QuerySet。在这种情况下,仓库中的金额总和。

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'.

接下来,添加一个包装函数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'