Django 管理者: データベースフィールドを持たないカスタム list_display フィールドの 1 つで並べ替える方法 質問する

Django 管理者: データベースフィールドを持たないカスタム list_display フィールドの 1 つで並べ替える方法 質問する
# 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 を手動で変更してこの列で並べ替えると、期待どおりに動作します。

ベストアンサー1

この問題に対する 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'

この方法では、管理インターフェース内でのみ注釈を付けます。実行するすべてのクエリで注釈を付けるわけではありません。

おすすめ記事