2017-03-07 11 views
2

のために並べ替えを有効にDjangoの管理者は、私は私のdbテーブルとモデル(:注文モデル名)で、次の二つのフィールドを持っている計算フィールド

list_display = (
    'order_number', 
    'branch', 
    'product', 
    'cost', 
    'quantity', 
    'calculated_total', 
    'status', 
    'ordered_at', 
) 

def calculated_total(self, obj): 
    return obj.cost * obj.quantity 
calculated_total.short_description = _('Total') 

ここでは、このフィールドのソートを有効にします。現実には、私がする必要があるすべては私のSELECTステートメントの列を追加することです:

SELECT (t.cost * t.quantity) as TOTAL 
ORDER BY TOTAL 

は、私はDjangoの管理者にソートするためのSQL文を追加することができます方法はありますか?

答えて

5

calculated_totalメソッドの結果ではご注文いただけません。

ただし、モデル管理者にはget_querysetメソッドを上書きし、同じものを計算するのはordering by an expressionにすることで、モデル管理者のデフォルトの順序を設定できます。

class OrderModelAdmin(admin.ModelAdmin): 
    ... 
    def get_queryset(self, request): 
     qs = super(OrderModelAdmin, self).get_queryset(request) 
     qs = qs.order_by(F('cost')*F('quantity')) 
     return qs 

同様の方法は、クエリーセットに合計を注釈し、そのフィールドで注文することです。コストがDecimalFieldであり、数量がIntegerFieldであると仮定すると、ExpressionWrapperを使用して出力フィールドを設定する必要があります。詳細はUsing F() with annotationsのドキュメントを参照してください。

totalを直接list_displayに使用することはできません。ただし、calculated_totalメソッドを変更して、注釈付きフィールドにアクセスすることはできます。 `calculated_total.admin_order_field = 'total'を設定して、Django管理者がその列をクリックすることでソートできるようにしました。

from django.db.models import F, ExpressionWrapper, DecimalField 

class OrderModelAdmin(admin.ModelAdmin): 
    list_display = ['name', 'number', 'price', 'calculated_total'] 

    def calculated_total(self, obj): 
     return obj.total 
    calculated_total.admin_order_field = 'total' 

    def get_queryset(self, request): 
     qs = super(OrderModelAdmin, self).get_queryset(request) 
     qs = qs.annotate(total=ExpressionWrapper(F('cost')*F('quantity'), output_field=DecimalField())).order_by('total') 
     return qs 
+0

注釈を使用していて、正しく機能していて、意味がありますが、上のコードでは微調整が必​​要でした。私は 'calculated_total.admin_order_field = 'total''を追加しなければなりませんでした。現実的には、これはまさに私が探していたものです。カスタム列を追加して、その列に基づいてそのフィールドをソートできるようにする。ありがとうございました! – Gasim

+0

@Gasim良い点!私の元の答えは、デフォルトではクエリーセットを合計でソートしました。列をクリックして並べ替えるには、 'admin_order_field'を設定する必要があります。私は答えにそれを加えました。 – Alasdair

関連する問題