就是在dashboard首頁有個圖表統計直觀展示一些數據,本例用的是用戶的角色及統計。
圖上信息可以看到,用戶100個,四種角色以及角色的人數和佔比,以此類推可以統計一些其他的信息。以下我嘗試簡單的闡述一下實現:
文件結構
這裡只是藍圖的結構,主要用到的是views.py視圖函數,models.py定義Dashboard類,提供一些查詢方法,以及模板文件dashboard.html。
@admin.route('')def dashboard(): group_and_count_users = Dashboard.group_and_count_users() return render_template('admin/page/dashboard.html', group_and_count_users=group_and_count_users)
可以看到視圖函數非常簡單,因為展示的數據內容也不提供什麼其他操作,所以只是簡單的返回一個模板文件。我們只要關注傳入的group_and_count_users這個參數就可以了,這是展示內容所需的數據,來自於資料庫的查詢。
Dashboardfrom sqlalchemy import funcfrom pms.blueprints.user.models import User, dbclass Dashboard(object): @classmethod def group_and_count_users(cls): """ 執行分組/統計所有用戶數量 :return: dict """ return cls._group_and_count(User, User.role) @classmethod def _group_and_count(cls, model, field): """ 根據指定的model和field統計。 :param model: Name of the model :type model: SQLAlchemy model :param field: Name of the field to group on :type field: SQLAlchemy field :return: dict """ count = func.count(field) query = db.session.query(count, field).group_by(field).all() results = { 'query': query, 'total': model.query.count() } return results
Dashboard類下定義了兩個classmethod,一個是group_and_count_users,其實只是調用了_group_and_count這個方法,傳入指定的model和field去查詢數據。這樣做是方便以後可以添加其他的方法,比如對Billing,Payments等的查詢統計,只要傳入對應的model和field就可以了。
對於sqlalchemy的用法不清楚的可以查詢官方文檔,或者自己定義一個簡單的User類,然後列印一下query的內容方便理解。
# 得到(數量, field)tuple 的列表query = db.session.query(count, field).group_by(field).all()
這裡重點看下這行,因為它就是我們統計百分比需要的重點數據,各個角色及對應的數量,這句查詢就是根據角色分組並統計相應的數量,返回結果是一個list,中間是由(COUNT,ROLE)這樣形式的tuple構成的。這樣我們返回的results這個dict就包含了我們統計想要的數據了。
將這些數據傳入模板後,就要靠bootstrap來處理了。
dashboard.html為了方便我用# 直接在代碼中注釋需要關注的內容。更多可以這裡的講解。
{% extends 'layouts/app.html' %}{% block body %} <div class="row"> <div class="col-md-4"> # 創建一個基本面板 <div class="panel panel-default"> # 添加面板標題 <div class="panel-heading"> <a href="{{ url_for('admin.index') }}">Users</a> # 靠右對齊用戶數量的值 <span class="pull-right text-muted"> {{ group_and_count_users.total }} </span> </div> # 面板內容 <div class="panel-body"> # 遍歷傳入的group_and_count_users參數,query鍵對應角色數據count,field {% for item in group_and_count_users.query %} # 計算percent的值,並用round過濾器保留整數部分 {% set percent = ((item[0] / group_and_count_users.total) * 100) | round %} <h5> # 獲取role,並用title過濾器大寫首字母 {{ item[1] | title}} # role的數量 <span class="text-muted">({{ item[0] }})</span> </h5> # progress是bootstrap提供的進度條,progress-striped條紋可選可選,active動畫效果可選 <div class="progress progress-striped active"> # 當前進度,最小進度,最大進度,style為佔有寬度百分比 <div class="progress-bar" role="progressbar" aria-valuenow="{{ percent }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percent }}%;"> {{ percent }}% </div> </div> {% endfor %} </div> </div> </div> </div>{% endblock %}
總結所有的流程就是,通過視圖函數獲得展示所需的數據並傳入模板文件,通過jinja2和bootstrap提供的panel面板及progress進度條組件展示效果。這種模式還常見於評分系統的分數分布。