本篇博客会先添加一张新用户相关的报表,然后提取两次添加报表相同的模块,对代码进行重构,方便之后的报表添加
对于一个应用来说新用户也是一个十分重要的观测数据
首先在数据库中新建一张new_user表并添加一些数据
CREATE TABLE new_user(`date` date,`province` varchar(20),`new_user` int,primary key(`date`, `province`)
);
INSERT INTO new_user VALUES('2021-01-01', 'Beijing', 10),('2021-01-01', 'Shanghai', 20),('2021-01-02', 'Beijing', 30);
按照日活报表相同的方法分别新增
new_user.js
$.ajax({url: "/data/new_user",type: "get",success: function (data) { let table = $('#new-user-table').DataTable();table.clear();let dataSet = [];for (let i = 0; i < data.length; ++i) {let rowSet = [];let detail = data[i];rowSet.push(detail["date"])rowSet.push(detail["province"])rowSet.push(detail["new_user"])dataSet.push(rowSet);}ws.add(dataSet).draw();lumns.adjust().draw();},
});
new_user.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /><meta name="description" content="" /><meta name="author" content="" /><title>Anne</title><link href=".11.2/css/jquery.dataTables.min.css" rel="stylesheet" /><link href="{{ url_for('static', filename='css/styles.css') }}" rel="stylesheet" /><script src=".15.3/js/all.min.js" crossorigin="anonymous"></script></head><body class="sb-nav-fixed"><nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark"><!-- Navbar Brand--><a class="navbar-brand ps-3" href="/">Anne</a><!-- Sidebar Toggle--><button class="btn btn-link btn-sm order-1 order-lg-0 me-4 me-lg-0" id="sidebarToggle" href="#!"><i class="fas fa-bars"></i></button></nav><div id="layoutSidenav"><div id="layoutSidenav_nav"><nav class="sb-sidenav accordion sb-sidenav-dark" id="sidenavAccordion"><div class="sb-sidenav-menu"><div class="nav"><div class="sb-sidenav-menu-heading">Core</div><a class="nav-link" href="/dau"><div class="sb-nav-link-icon"><i class="fas fa-tachometer-alt"></i></div>DAU</a><a class="nav-link" href="/new_user"><div class="sb-nav-link-icon"><i class="fas fa-tachometer-alt"></i></div>New User</a></div></div></nav></div><div id="layoutSidenav_content"><main><div class="container-fluid px-4"><div class="card mb-4"><div class="card-header"><i class="fas fa-table me-1"></i>New User</div><div class="card-body"><table id="new-user-table"><thead><tr><th>Date</th><th>Province</th><th>New User</th></tr></thead><tfoot><tr><th>Date</th><th>Province</th><th>New User</th></tr></tfoot><tbody></tbody></table></div></div></div></main></div></div><script src="@5.1.0/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script><script src="{{ url_for('static', filename='js/scripts.js') }}"></script><script src=".6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script><script src=".11.2/js/jquery.dataTables.min.js"></script><script src="{{ url_for('static', filename='js/new_user.js') }}"></script></body>
</html>
以及相关db model和路由
class NewUser(db.Model):__tablename__ = "new_user"__table_args__ = {"autoload": True,"autoload_with": db.engine}ute("/data/new_user")
def data_new_user():data = NewUser.query.all()ret = []for row in data:ret.append({"date": row.date.strftime("%Y-%m-%d"),"province": row.province,"new_user": w_user,})return jsonify(ret)ute("/new_user")
def new_user():return render_template("new_user.html")
这样一张新的报表就完成了
观察两张报表的代码不难发现除了部分内容不同外,绝大部分内容是相同的。如果每次新增报表都需要这样写一遍代码,整个添加报表的过程显得十分的低效并且会使得代码变得臃肿。因此可以将其中共性的部分提取出来,从而简化新增报表的流程
js代码的差异主要是URL,table的id以及data的处理三个部分
对于table的id而言,目前一个页面只有一张报表,这个情况下,可以将table的id固定下来
对于data的处理,可以通过修改data传输的格式来解决
最终js文件为data.js,代码如下
let query_data = function(url) {$.ajax({url: url,type: "get",success: function (data) { let table = $('#data-table').DataTable();table.clear();ws.add(data).draw();lumns.adjust().draw();},});
};
Flask使用jinjia2来渲染页面,因此可以做到页面内的不同信息通过参数的方式在render_template的时候传入
在jinjia2中可以会将双引号内的内容进行替换,比如下面的html
<!DOCTYPE html>
<html>{{ message }}
</html>
通过python调用render_template
ute("/jinjia2")
def jinjia2():return render_template("jinjia2.html", message = "Hello Anne")
最终会将页面渲染为
<!DOCTYPE html>
<html>Hello Anne
</html>
通过这个方式可以将表头的标题进行替换,
但通常来说,一张表的列数是不固定的,无法预先定义,在jinjia2中可以通过{%for%}来处理循环
比如对于页面
<!DOCTYPE html>
<html>{% for message in messages %}<div>{{ message }}</div>{% endfor %}
</html>
通过python调用render_template
ute("/jinjia2")
def jinjia2():return render_template("jinjia2.html", messages = ["Hello Anne", "Hello Hathaway"])
最终会将页面渲染为
<!DOCTYPE html>
<html><div>Hello Anne</div><div>Hello Hathaway</div></html>
可以看到渲染出的html中有许多的空白行
通过jinjia2可以通过Whitespace Control,修改空行和缩进,但仍然无法完美解决问题,需要通过添加换行以及loop的检测,最终的html模板为
<!DOCTYPE html>
<html>{% for message in messages -%}<div>{{ message }}</div>{{"" if not loop.last }}{%- endfor %}
</html>
渲染出的页面为
<!DOCTYPE html>
<html><div>Hello Anne</div><div>Hello Hathaway</div>
</html>
通过使用render_template函数以及jinjia2的循环,可以实现通过通过参数动态的渲染出页面
最终的html页面代码如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /><meta name="description" content="" /><meta name="author" content="" /><title>Anne</title><link href=".11.2/css/jquery.dataTables.min.css" rel="stylesheet" /><link href="{{ url_for('static', filename='css/styles.css') }}" rel="stylesheet" /><script src=".15.3/js/all.min.js" crossorigin="anonymous"></script></head><body class="sb-nav-fixed"><nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark"><!-- Navbar Brand--><a class="navbar-brand ps-3" href="/">Anne</a><!-- Sidebar Toggle--><button class="btn btn-link btn-sm order-1 order-lg-0 me-4 me-lg-0" id="sidebarToggle" href="#!"><i class="fas fa-bars"></i></button></nav><div id="layoutSidenav"><div id="layoutSidenav_nav"><nav class="sb-sidenav accordion sb-sidenav-dark" id="sidenavAccordion"><div class="sb-sidenav-menu"><div class="nav"><div class="sb-sidenav-menu-heading">Core</div><a class="nav-link" href="/dau"><div class="sb-nav-link-icon"><i class="fas fa-tachometer-alt"></i></div>DAU</a><a class="nav-link" href="/new_user"><div class="sb-nav-link-icon"><i class="fas fa-tachometer-alt"></i></div>New User</a></div></div></nav></div><div id="layoutSidenav_content"><main><div class="container-fluid px-4"><div class="card mb-4"><div class="card-header"><i class="fas fa-table me-1"></i>{{ title }}</div><div class="card-body"><table id="data-table"><thead><tr>{% for col in cols -%}<th>{{ col }}</th>{{"" if not loop.last }}{%- endfor %}</tr></thead><tfoot><tr>{% for col in cols -%}<th>{{ col }}</th>{{"" if not loop.last }}{%- endfor %}</tr></tfoot><tbody></tbody></table></div></div></div></main></div></div><script src="@5.1.0/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script><script src="{{ url_for('static', filename='js/scripts.js') }}"></script><script src=".6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script><script src=".11.2/js/jquery.dataTables.min.js"></script><script src="{{ url_for('static', filename='js/data.js') }}"></script><script>query_data("{{ data_url }}")</script></body>
</html>
Flask可以通过add_url_rule的方式来添加路由,通过对python代码的抽象,选择将相同的内容抽象成一个类
class TableModel():title = ""cols = []uri = ""db_model = Nonedef __init__(self, title, cols, uri, db_model, app):self.title = ls = colsself.uri = uriself.db_model = db_modelif app is not ister_app(app)def register_app(self, app):app.add_url_rule(self.url, dpoint, der)app.add_url_rule(self.data_url, self.data_endpoint, self.data)@propertydef url(self):return f"/{self.uri}"@propertydef endpoint(self):return self.uridef render(self):return render_template("table.html", title=self.title, colsls, data_url=self.data_url)@propertydef data_url(self):return f"/data/{self.uri}"@propertydef data_endpoint(self):return f"data.{self.uri}"def data(self):data = self.db_model.query.all()ret = []for row in data:ret.append(row.table_row)return jsonify(ret)
这样新增一张报表只需要
class DAU(db.Model):__tablename__ = "DAU"__table_args__ = {"autoload": True,"autoload_with": db.engine}@propertydef table_row(self) -> list:return [self.date.strftime("%Y-%m-%d"),self.province,self.DAU,]TableModel("DAU", ["Date", "Province", "DAU"], "dau", DAU, app)
大大简化了新增报表需要的代码量
本文发布于:2024-02-08 19:48:09,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170739300768467.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |