如何在Django Admin中按多个自定义方法排序

1 投票
1 回答
1302 浏览
提问于 2025-04-18 12:45

我想在Django后台能够通过几个自定义的方法进行排序。这个问题只提供了一个方法的解决方案。

我尝试修改它:

from django.db import models

class CustomerAdmin(admin.ModelAdmin):
    list_display = ('number_of_orders','number_of_somevalue') # added field

    def queryset(self, request):
        qs = super(CustomerAdmin, self).queryset(request)
        qs = qs.annotate(models.Count('order'))
        qs = qs.annotate(models.Count('somevalue')) # added line
        return qs

    def number_of_orders(self, obj):
        return obj.order__count
    number_of_orders.admin_order_field = 'order__count'

    def number_of_somevalue(self, obj): # added method
        return obj.somevalue__count
    number_of_somevalue.admin_order_field = 'somevalue__count'

但是它的效果不对。看起来它把count的值相乘了,而不是分别计算。

举个例子:

我有2个订单和2个某些值,但在面板上我看到的是4个订单和4个某些值。

再加上另一个方法和另一个值,结果变成了8(2*2*2)。

我该如何修复这个问题呢?

1 个回答

1

你可以试试这个方法来按照多种自定义方式进行排序(已经测试过了):

from django.db.models import Count

class CustomerAdmin(admin.ModelAdmin):

    # The list display must contain the functions that calculate values
    list_display = ('number_of_orders','number_of_somevalue') # added field

    # Overwrite queryset in model admin
    def queryset(self, request):
        qs = super(CustomerAdmin, self).queryset(request)
        # The query have to return multiple annotation, for this use distinct=True in the Count function
        qs = qs.annotate(number_orders = Count('order', distinct=True)).annotate(number_somevalue = Count('somevalue',distinct=True)) 
        return qs

    # This function return the new field calculated in queryset (number_orders)
    def number_of_orders(self, obj):
        return obj.number_orders

    number_of_orders.admin_order_field = 'numberorders' # sortable new column

    # And this one will return the another field calculated (number_somevalue)
    def number_of_somevalue(self, obj): # added method
        return obj.number_somevalue

    number_of_somevalue.admin_order_field = 'number_somevalue'# sortable new column

撰写回答