行のリストを表示するために、標準の django 管理モジュールを使用しています。列の 1 つは数値フィールドです。すべてのオブジェクトの合計である数値列を除いて、ほとんどの列が空白になっている追加の「合計」行を表示したいと思います。
管理モジュール内でこれを行う簡単な方法はありますか、それともカスタム ビューを作成したほうがよいでしょうか?
私はジャンゴ1.2を使用しています。
行のリストを表示するために、標準の django 管理モジュールを使用しています。列の 1 つは数値フィールドです。すべてのオブジェクトの合計である数値列を除いて、ほとんどの列が空白になっている追加の「合計」行を表示したいと思います。
管理モジュール内でこれを行う簡単な方法はありますか、それともカスタム ビューを作成したほうがよいでしょうか?
私はジャンゴ1.2を使用しています。
はい、さまざまな方法で実行できますが、ほとんどのdjango-istの方法は次のとおりです。
最初にデフォルトのdjangoリストビューをオーバーライドします...そして新しいテンプレートファイルディレクトリを指定します
ModelAdmin.changelist_view(self, request, extra_context=None)
好き:
class MyModelAdmin(admin.ModelAdmin):
# A template for a very customized change view:
change_list_template = 'admin/myapp/extras/sometemplate_change_form.html'
def get_total(self):
#functions to calculate whatever you want...
total = YourModel.objects.all().aggregate(tot=Sum('total'))['tot']
return total
def changelist_view(self, request, extra_context=None):
my_context = {
'total': self.get_total(),
}
return super(MyModelAdmin, self).changelist_view(request,
extra_context=my_context)
したがって、リストビューコンテキストに「合計」を追加して、合計値を保持し、それをテンプレートに渡します。
change_list_templateが設定される場合、djangoはそのテンプレートを使用します。それ以外の場合、djangoは標準のdjangoテンプレートを使用します。
def changelist_view (self、request、extra_context = None)が呼び出された場合、djangoはその関数を使用してコンテンツを作成します。それ以外の場合は、デフォルトのdjangoビューを使用します。
次に、admin/myapp/extras/sometemplate_change_form.html
ファイルを作成して{{total}}
、任意の場所に配置します。
管理者テンプレートをオーバーライドする方法のガイド そして、ここに管理者ビューをオーバーライドする方法があります
更新:aggregate
合計を計算するための簡単なものを追加します。編集して、必要に応じて設定できます。
UPDATE 2:ModelAdminテンプレートオーバーライドオプションがからModelAdmin.change_form_template
に修正されましたModelAdmin.change_list_template
。(ありがとうc4urself)。はい。ただし、デフォルトのdjango adminテンプレートを変更することは、他の多くのModelAdminで使用されており、関連するテンプレートが更新されると問題が発生する可能性があるため、非常に悪い選択です。
注意:
フィルターを使用しても合計は変わりません。以下のコメントを参照してください。
これを行う Django の方法は、django の管理アプリが使用する ChangeList クラスをオーバーライドすることだと思います。django 1.2 でこれを行うget_changelist
には、admin クラスでメソッドを呼び出します。私の例TomatoAdmin
では、カスタムChangeList calssを返すこのメソッドを呼び出します。この ChangeList クラス:MyChangeList
のコンテキストに追加の属性を追加するだけですchange_list.html
。
change_list.html が次のディレクトリにあることを確認します。
app_label/change_list.html
例では、これは次のとおりです: templates/admin/tomato/change_list.html
models.py (整数フィールドを持つ単純なモデル)
class CherryTomato(models.Model):
name = models.CharField(max_length=100)
num_in_box = models.IntegerField()
admin.py (あなたの Admin クラスとカスタム ChangeList クラス)
from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
from django.db.models import Count, Sum
from tomatoes.tomato.models import CherryTomato
class MyChangeList(ChangeList):
def get_results(self, *args, **kwargs):
super(MyChangeList, self).get_results(*args, **kwargs)
q = self.result_list.aggregate(tomato_sum=Sum('num_in_box'))
self.tomato_count = q['tomato_sum']
class TomatoAdmin(admin.ModelAdmin):
def get_changelist(self, request):
return MyChangeList
class Meta:
model = CherryTomato
list_display = ('name', 'num_in_box')
admin.site.register(CherryTomato, TomatoAdmin)
change_list.html (該当ビットのみ、既存のものをコピペして拡張)
{% block result_list %}
{% if action_form and actions_on_top and cl.full_result_count %}{% admin_actions %}{% endif %}
{% result_list cl %}
{% if action_form and actions_on_bottom and cl.full_result_count %}{% admin_actions %}{% endif %}
Tomatoes on this page: {{ cl.tomato_count }}
{% endblock %}
これをあなたが望むようにスタイルする方法はあなたに任せます。
わかりました。新しいテンプレート タグをいくつか追加し、管理テンプレートを拡張することで、これを行う方法があります。
まず、アプリのtemplatetags
フォルダーでadmin_totals.py
、合計行を作成するためのテンプレート タグを含むファイルを作成します。
from django.template import Library
register = Library()
def totals_row(cl):
total_functions = getattr(cl.model_admin, 'total_functions', {})
totals = []
for field_name in cl.list_display:
if field_name in total_functions:
values = [getattr(i, field_name) for i in cl.result_list]
totals.append(total_functions[field_name](values))
else:
totals.append('')
return {'cl': cl, 'totals_row': totals}
totals_row = register.inclusion_tag("myapp/totals_row.html")(totals_row)
次に、その行のテンプレートが必要ですmyapp/totals_row.html
(テンプレートがある場所に関係なく):
<table id="result_totals">
<tfoot>
<tr>
{% for total in totals_row %}<td>{{ total }}</td>{% endfor %}
</tr>
</tfoot>
</table>
次に、次のように、Django のデフォルトから継承するカスタム管理テンプレートにそれを配線する必要がありますmyapp/mymodel_admin.html
。
{% extends "admin/change_list.html" %}
{% load admin_totals %}
{% block result_list %}
{{ block.super }}
{% totals_row cl %}
{% endblock %}
最後に、それをadmin.py
アプリのファイルの構成に配線します。
class MyModelAdmin(ModelAdmin):
list_display = ('name', 'date', 'numerical_awesomeness')
total_functions = {'numerical_awesomeness': sum}
change_list_template = 'myapp/mymodel_admin.html'
これにより、新しいモデルのカスタム管理テンプレートが配線され、合計行が表示されます。必要に応じて、 以外の集計関数で拡張することもできsum
ます。
残りの小さなポイント: 合計行は実際には結果テーブルにはありません。これは、Django 管理テンプレートのかなり危険なコピー アンド ペーストが必要になるためです。おまけとして、次の JavaScript をtotals_row.html
ファイルの末尾に追加できます。
<script type="text/javascript">
django.jQuery('#result_list').append(django.jQuery('#result_totals tfoot')[0])
django.jQuery('#result_totals').remove()
</script>
1 つの注意点: これはすべて、存在するすべてのアイテムではなく、現在表示されているアイテムの合計のみを反映します。これを回避する1つの方法は、潜在的なパフォーマンスへの影響を気にしない場合、クラスにlist_per_page
実行不可能なほど大きな数を設定することです。ModelAdmin
管理ビューをオーバーライドするカスタム ビューを作成すると、現在のページ情報とともにクエリセットを取得し、データをスライスして現在のページに適した合計を作成できるはずです。真の合計が必要な場合は、探しているオプションとしてカスタムの上書きされた管理ビューがまだ表示されます。
私の知る限り、カスタム ビューを作成せずにこれを行う方法はありません。ユーザーは、クエリセット内のすべてのオブジェクトではなく、表示されているオブジェクトのみの合計がそのような行に表示されることを期待するため、この概念には少し欠陥があります。したがって、ページネーションは混乱を招きます。
余談ですが、次のようにして、管理リスト ビューに列を追加できます。
class ItemAdmin(admin.ModelAdmin):
model = Item
list_display = ('field1', 'field2', 'extra_field')
def extra_field(self, obj):
return u'%s' % do_something_with(obj)