標準のDjango adminモジュールを使用して行のリストを表示しています。列の1つは数値フィールドです。ほとんどの場合、追加の「合計」行を表示したいと思います。すべてのオブジェクトの合計である数値列を除いて、列は空白として表示されます。
管理モジュール内でこれを行う簡単な方法はありますか、それともカスタムビューを作成する方が良いですか?
私はDjango 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テンプレートを使用します。
def changelist_view(self、request、extra_context = None)が呼び出された場合、Djangoはその関数を使用してコンテンツを作成します。それ以外の場合は、デフォルトのDjangoビュー。
次に、admin/myapp/extras/sometemplate_change_form.html
ファイルを作成し、{{total}}
を任意の場所に配置します。
方法のガイド 管理者テンプレートを上書きする そしてここに方法があります 管理者ビューを上書きする
UPDATE:単純なaggregate
を追加して合計を計算します。編集して、必要に応じて設定できます。
UPDATE 2:ModelAdminテンプレートオーバーライドオプションがModelAdmin.change_form_template
からModelAdmin.change_list_template
に修正されました。 (ありがとうc4urself)。はい。ただし、デフォルトのDjango adminテンプレートを変更することは、他の多くのModelAdminで使用されており、関連するテンプレートが更新されると問題が発生する可能性があるため、非常に悪い選択です。
[〜#〜] nb [〜#〜]:
フィルターを使用しても合計は変わりません。以下のコメントを参照してください。
Djangoこれを行う方法は、Djangoの管理アプリが使用するChangeListクラスをオーバーライドすることだと思います。Django 1.2で、get_changelist
メソッドを呼び出すことにより、これを行います。私の例では、TomatoAdmin
がこのメソッドを呼び出してカスタムChangeList計算を返します。この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>
次に、それをmyapp/mymodel_admin.html
などのDjangoのデフォルトを継承するカスタム管理テンプレートにワイヤリングする必要があります。
{% 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管理者テンプレートのかなり厄介なコピーと貼り付けが必要になるためです。ボーナスポイントについては、追加できますtotals_row.html
ファイルの下部にあるJavaScriptの次のsmidge:
<script type="text/javascript">
Django.jQuery('#result_list').append(Django.jQuery('#result_totals tfoot')[0])
Django.jQuery('#result_totals').remove()
</script>
注意点:これはすべて、存在するすべてのアイテムではなく、現在表示されているアイテムの合計のみを反映します。これを回避する1つの方法は、パフォーマンスへの潜在的な影響を気にしない場合は、list_per_page
をModelAdmin
クラスで実行不可能なほど大きな数に設定することです。
このスレッドはしばらく続いていますが、私はおそらくそのような機能を探している最後のスレッドではありません。そこで、合計を簡単に追加できるパッケージを作成しました。
チェックアウト https://github.com/douwevandermeij/admin-totals
使用法:
from admin_totals.admin import ModelAdminTotals
from Django.contrib import admin
from Django.db.models import Sum, Avg
@admin.register(MyModel)
class MyModelAdmin(ModelAdminTotals):
list_display = ['col_a', 'col_b', 'col_c']
list_totals = [('col_b', Sum), ('col_c', Avg)]
気軽にフォークして改良してください。
要約統計量を提供できるパッケージ「Django-admin-changelist-stats」もあります。 Django 1.6プロジェクトで正常に使用しました。
IMOは、きめ細かいテンプレートのカスタマイズにc4urselfのソリューションを使用しますが、テーブルの集計(sum/avg/min/max)のみが必要な場合は、このソリューションは非常に優れています。
そのウェブサイトから
「このシンプルなアプリケーションは、Django管理者チェンジリストビューの統計と集計機能を提供します。モデル管理者に1つのオプションを追加するだけで、チェンジリストページの最後に統計を簡単に表示できます。オブジェクト。」
例を含む詳細情報は、bitbucketリポジトリのWebページにあります https://bitbucket.org/frankban/Django-admin-changelist-stats/src
管理ビューを上書きするカスタムビューを作成する場合は、クエリセットを現在のページ情報と一緒に取得し、データをスライスして、現在のページに適切な合計を作成できるはずです。真の合計が必要な場合でも、探しているオプションとしてカスタムオーバーライドされた管理ビューが表示されます。