gpt4 book ai didi

python - 如何为 Flask-Admin 添加摘要行?

转载 作者:行者123 更新时间:2023-11-28 21:03:02 24 4
gpt4 key购买 nike

在我的 flask-admin index_view 中,我正在显示我的行的财务信息。

我想在我的 index_view 表的底部添加一个额外的行,“summary row”,它汇总了所有列。

我怎样才能做到这一点?

enter image description here

最佳答案

您需要做几件事。提供自定义 list.html 模板并覆盖 View 的 render() 方法。在 render 方法中将您的摘要数据注入(inject) kwargs,并在自定义模板中使用摘要数据输出适当的 html。您可以将汇总数据添加到现有数据表的末尾,或将其添加到单独的表中,如下例所示。

Flask-Admin Summary Table

这是一个使用 Flask-Admin 1.5、SQLAlchemy 和 SQLite 的独立示例(两个文件)。 custom_list.html 直接取自 flask-admin list.html,我们正在处理从第 68 行开始的 block :

{% block model_list_table %}
...
{% endblock %}

请注意,在 render() 方法中,摘要数据是一个字典数组。每个字典都有一个 'title' 属性(例如 'title: 'Page Total' 加上每个列摘要数据都需要一个属性。

app.py

import random
import string

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin.contrib.sqla import ModelView
from flask_admin import Admin, expose

# Create application
from sqlalchemy import func

app = Flask(__name__)

# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456790'

# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
db = SQLAlchemy(app)


# Flask views
@app.route('/')
def index():
return '<a href="/admin/">Click me to get to Admin!</a>'


class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), nullable=False, unique=True)
cost = db.Column(db.Integer(), nullable=False)

def __str__(self):
return unicode(self).encode('utf-8')

def __unicode__(self):
return "Name: {name}; Cost : {cost}".format(name=self.name, cost=self.cost)


class ProjectView(ModelView):
# don't call the custom page list.html as you'll get a recursive call
list_template = 'admin/model/custom_list.html'
form_columns = ('name', 'cost')
page_size = 5

def page_cost(self, current_page):
# this should take into account any filters/search inplace
_query = self.session.query(Project).limit(self.page_size).offset(current_page * self.page_size)
return sum([p.cost for p in _query])

def total_cost(self):
# this should take into account any filters/search inplace
return self.session.query(func.sum(Project.cost)).scalar()

def render(self, template, **kwargs):
# we are only interested in the list page
if template == 'admin/model/custom_list.html':
# append a summary_data dictionary into kwargs
_current_page = kwargs['page']
kwargs['summary_data'] = [
{'title': 'Page Total', 'name': None, 'cost': self.page_cost(_current_page)},
{'title': 'Grand Total', 'name': None, 'cost': self.total_cost()},
]
return super(ProjectView, self).render(template, **kwargs)


admin = Admin(app, template_mode="bootstrap3")
admin.add_view(ProjectView(Project, db.session))


def build_sample_db():
db.drop_all()
db.create_all()

for _ in range(0, 100):
_cost = random.randrange(1, 1000)
_project = Project(
name=''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)),
cost=_cost
)
db.session.add(_project)

db.session.commit()


if __name__ == '__main__':
build_sample_db()
app.run(port=5000, debug=True)

templates/admin/model/custom_list.html

{% extends 'admin/model/list.html' %}

{% block model_list_table %}
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover model-list">
<thead>
<tr>
{% block list_header scoped %}
{% if actions %}
<th class="list-checkbox-column">
<input type="checkbox" name="rowtoggle" class="action-rowtoggle" title="{{ _gettext('Select all records') }}" />
</th>
{% endif %}
{% block list_row_actions_header %}
{% if admin_view.column_display_actions %}
<th class="col-md-1">&nbsp;</th>
{% endif %}
{% endblock %}
{% for c, name in list_columns %}
{% set column = loop.index0 %}
<th class="column-header col-{{c}}">
{% if admin_view.is_sortable(c) %}
{% if sort_column == column %}
<a href="{{ sort_url(column, True) }}" title="{{ _gettext('Sort by %(name)s', name=name) }}">
{{ name }}
{% if sort_desc %}
<span class="fa fa-chevron-up glyphicon glyphicon-chevron-up"></span>
{% else %}
<span class="fa fa-chevron-down glyphicon glyphicon-chevron-down"></span>
{% endif %}
</a>
{% else %}
<a href="{{ sort_url(column) }}" title="{{ _gettext('Sort by %(name)s', name=name) }}">{{ name }}</a>
{% endif %}
{% else %}
{{ name }}
{% endif %}
{% if admin_view.column_descriptions.get(c) %}
<a class="fa fa-question-circle glyphicon glyphicon-question-sign"
title="{{ admin_view.column_descriptions[c] }}"
href="javascript:void(0)" data-role="tooltip"
></a>
{% endif %}
</th>
{% endfor %}
{% endblock %}
</tr>
</thead>
{% for row in data %}
<tr>
{% block list_row scoped %}
{% if actions %}
<td>
<input type="checkbox" name="rowid" class="action-checkbox" value="{{ get_pk_value(row) }}" title="{{ _gettext('Select record') }}" />
</td>
{% endif %}
{% block list_row_actions_column scoped %}
{% if admin_view.column_display_actions %}
<td class="list-buttons-column">
{% block list_row_actions scoped %}
{% for action in list_row_actions %}
{{ action.render_ctx(get_pk_value(row), row) }}
{% endfor %}
{% endblock %}
</td>
{%- endif -%}
{% endblock %}

{% for c, name in list_columns %}
<td class="col-{{c}}">
{% if admin_view.is_editable(c) %}
{% set form = list_forms[get_pk_value(row)] %}
{% if form.csrf_token %}
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c), csrf=form.csrf_token._value()) }}
{% else %}
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c)) }}
{% endif %}
{% else %}
{{ get_value(row, c) }}
{% endif %}
</td>
{% endfor %}
{% endblock %}
</tr>
{% else %}
<tr>
<td colspan="999">
{% block empty_list_message %}
<div class="text-center">
{{ admin_view.get_empty_list_message() }}
</div>
{% endblock %}
</td>
</tr>
{% endfor %}
</table>
</div>

<h3>Summaries</h3>

<div class="table-responsive">
<table class="table table-striped table-bordered table-hover model-list">
<thead>
<tr>
{% if actions %}
<th class="list-checkbox-column">
</th>
{% endif %}

<th class="col-md-1"></th>
{% for c, name in list_columns %}
{% set column = loop.index0 %}
<th class="column-header col-{{c}}">
{{ name }}
</th>
{% endfor %}
</tr>
</thead>
{% for row in summary_data %}
<tr>
<td colspan="2"><strong>{{ row['title'] or ''}}</strong></td>
{% for c, name in list_columns %}
<td class="col-{{c}}">
{{ row[c] or ''}}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
</div>


{% block list_pager %}
{% if num_pages is not none %}
{{ lib.pager(page, num_pages, pager_url) }}
{% else %}
{{ lib.simple_pager(page, data|length == page_size, pager_url) }}
{% endif %}
{% endblock %}
{% endblock %}

关于python - 如何为 Flask-Admin 添加摘要行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47124728/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com