首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Django admin:如何根据没有数据库字段的自定义list_display字段之一进行排序

Django admin:如何根据没有数据库字段的自定义list_display字段之一进行排序
EN

Stack Overflow用户
提问于 2010-01-31 00:06:01
回答 3查看 57.5K关注 0票数 136
代码语言:javascript
复制
# admin.py
class CustomerAdmin(admin.ModelAdmin):  
    list_display = ('foo', 'number_of_orders')


# models.py
class 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依赖底层DB来执行排序?在这里,创建一个包含订单数的聚合字段似乎有点夸张。

有趣的是:如果您在浏览器中手动更改url来对此列进行排序,它将按预期工作!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-17 02:00:39

我喜欢Greg对这个问题的解决方案,但我想指出的是,您可以直接在管理员中做同样的事情:

代码语言:javascript
复制
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'

这样,您只需在管理界面内进行注释。并不是你做的每一个查询。

票数 179
EN

Stack Overflow用户

发布于 2010-03-01 06:40:22

我还没有测试过这一点(我很想知道它是否有效),但是如何为Customer定义一个自定义管理器,其中包括聚合的订单数,然后将admin_order_field设置为该聚合,即

代码语言:javascript
复制
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子类化!

票数 52
EN

Stack Overflow用户

发布于 2010-02-02 23:38:25

我能想到的唯一方法就是去规格化这个字段。也就是说,创建一个真实的字段,get更新后与派生它的字段保持同步。我通常通过使用非规范化字段或其派生的模型覆盖在eith模型上的save来完成此操作:

代码语言:javascript
复制
# 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[...]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2168475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档