为了账号安全,请及时绑定邮箱和手机立即绑定

Django Admin:如何按没有数据库字段的自定义list_display字段之一排序

Django Admin:如何按没有数据库字段的自定义list_display字段之一排序

ABOUTYOU 2019-12-09 15:12:22
# admin.pyclass CustomerAdmin(admin.ModelAdmin):      list_display = ('foo', 'number_of_orders')# models.pyclass Order(models.Model):    bar = models.CharField[...]    customer = models.ForeignKey(Customer)class Customer(models.Model):    foo = models.CharField[...]    def number_of_orders(self):        return u'%s' % Order.objects.filter(customer=self).count()  如何根据客户对客户进行分类number_of_orders?admin_order_field属性不能在这里使用,因为它需要一个数据库字段进行排序。Django依赖底层数据库执行排序,这有可能吗?创建一个包含订单数量的汇总字段似乎在这里是过大的。有趣的是:如果您在浏览器中手动更改url以在此列上进行排序-它将按预期工作!
查看完整描述

3 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

我喜欢Greg解决此问题的方法,但我想指出,您可以直接在管理员中执行相同的操作:


from django.db import models


class CustomerAdmin(admin.ModelAdmin):

    list_display = ('number_of_orders',)


    def get_queryset(self, request):

    # def queryset(self, request): # For Django <1.6

        qs = super(CustomerAdmin, self).get_queryset(request)

        # qs = super(CustomerAdmin, self).queryset(request) # For Django <1.6

        qs = qs.annotate(models.Count('order'))

        return qs


    def number_of_orders(self, obj):

        return obj.order__count

    number_of_orders.admin_order_field = 'order__count'

这样,您只需在管理界面内进行注释。并非与您执行的每个查询有关。


查看完整回答
反对 回复 2019-12-09
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

我尚未对此进行测试(我想知道它是否有效),但是如何定义一个自定义管理器,Customer其中包括汇总的订单数,然后设置admin_order_field为该汇总,即


from django.db import models 



class CustomerManager(models.Manager):

    def get_query_set(self):

        return super(CustomerManager, self).get_query_set().annotate(models.Count('order'))


class Customer(models.Model):

    foo = models.CharField[...]


    objects = CustomerManager()


    def number_of_orders(self):

        return u'%s' % Order.objects.filter(customer=self).count()

    number_of_orders.admin_order_field = 'order__count'

编辑:我刚刚测试了这个想法,它完美地工作-不需要django admin子类化!


查看完整回答
反对 回复 2019-12-09
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

我能想到的唯一方法是对字段进行非规范化。也就是说-创建一个实际字段,该字段将进行更新以与它所源自的字段保持同步。我通常通过覆盖带有非规范化字段的模型或其衍生模型来保存:


# models.py

class Order(models.Model):

    bar = models.CharField[...]

    customer = models.ForeignKey(Customer)

    def save(self):

        super(Order, self).save()

        self.customer.number_of_orders = Order.objects.filter(customer=self.customer).count()

        self.customer.save()


class Customer(models.Model):

    foo = models.CharField[...]

    number_of_orders = models.IntegerField[...]


查看完整回答
反对 回复 2019-12-09
  • 3 回答
  • 0 关注
  • 1323 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信