FastAPI后端查询数据在前端进行分页展示
前言
小编知道FastAPI是一个高效异步的python WEB框架、之前也接触过flask。
这篇文章主要针对Fastapi异步WEB框架的前后端分离实战,到底是怎么分?怎么离?怎么交互数据?相信很多小伙伴也是模模糊糊,网络上各种零碎的知识让很多人头晕目眩,不知道从何下手。
今天小编就来讲讲FastAPI如何与LayUImini及mysql实行交互数据,目前互联网上的这块资料非常少,现在小编将简单的介绍一下。该程序主要是演示通过F查询数据在前端进行分页展示。
主要用的技术有:
1、fastAPI的主路由和分路由的建立(大型工程需要用该技术)
2、fastAPI查询参数的写法
3、后端SQL语句查询
4、分页技术
最后展示的效果如下图:(搜索和编辑功能未做)
提示:以下是本篇文章正文内容,下面案例可供参考。
我们先来说说mysql 的使用。因为要用到数据库,小编觉得先从数据开始说起比较好。
一、mysql的使用?
mysql的安装运用不是本文的重点,请自行搜索相关资料。mysql应该有400多M。下载社区版进行安装。
数据准备
下载:https://download.youkuaiyun.com/download/weixin_43354347/16795733
2016城市编码(身份证号归属地查询),该数据有46966条。
将该文件导入mysql数据库并起表名:address_code
address_code里面的数据大概是这个样子的:
二、FastAPI的使用步骤
1.建立主程序文件app.py
代码如下(示例):
import uvicorn #导入异步WEB服务器uvicorn
from fastapi import FastAPI
from starlette.requests import Request #后面会用到,请求静态资源文件要用到请求的类型
from starlette.templating import Jinja2Templates #主要功能是导入jinjia2的模板引擎类
from fastapi.staticfiles import StaticFiles #主要功能是导入静态文件类,因为我们要用到js、CSS
import address_code #导入自己编写的模块,主要是要用到注册到主路由上面
from starlette.templating import Jinja2Templates
templates = Jinja2Templates(directory='templates') # 模板实例化,一会要用到
app = FastAPI() #app的实例化
app.mount("/static", StaticFiles(directory="static"), name="static") # 加载静态文件
@app.get("/") # 访问html,固定写法
async def main(request: Request):
return templates.TemplateResponse('list.html', {'request': request})
app.include_router(address_code.router) #将导入的address_code路由注册到主路由上
if __name__ == '__main__':
uvicorn.run('app:app', host="0.0.0.0",port=8000, reload=True)
2.建立一个address_code.py文件
代码如下(示例):
from fastapi import APIRouter,Request
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='123456',
database='各种数据', charset='utf8', cursorclass=pymysql.cursors.DictCursor)
router=APIRouter(tags=['身份和地址查询']) #
@router.get("/item/") #访问接口,要与前端js代码里面的一致
async def read_item(page: int, limit: int): #使用的FastAPI查询参数的固定写法,因为前端layuimini传送page和limit参数过来,现在后端来处理
sql = "select * from address_code limit %s,%s" % ((page-1)*limit, limit) # 第一页的0加到14条,%s是python字符串占位符的,请深刻理解这条语句
print(sql)
cursor = conn.cursor()
try:
cursor.execute(sql)
print("所有数据查询语句已经执行了")
print(sql)
result = cursor.fetchall()
print(result)
return {"code": 0, "msg": "信息有了", "count": count_db(), "data": result} #这是layuimini返回json的要求格式,主要的要得到count和data,注意 count_db()调用了下面的函数主要统计条数
except pymysql.Error as e:
print(e)
def count_db(): #统计数据的条目的函数,要用到
sql = "select count(*) from address_code" #统计条数
print(sql)
cursor = conn.cursor()
try:
cursor.execute(sql)
d= cursor.fetchall()
for x in d:
a=x.get('count(*)')
print(a)
return (a)
except pymysql.Error as e:
print(e)
finally:
cursor.close()
三、前端框架LayUImini的使用?
1、LayUI是什么?
layui是我们国人开发的前端框架
layui(谐音:类 UI) 是一套开源的 Web UI 解决方案,采用自身经典的模块化规范,并遵循原生 HTML/CSS/JS 的开发方式,极易上手,拿来即用。其风格简约轻盈,而组件优雅丰盈,从源代码到使用方法的每一处细节都经过精心雕琢,非常适合网页界面的快速开发。layui 区别于那些基于 MVVM 底层的前端框架,却并非逆道而行,而是信奉返璞归真之道。准确地说,它更多是面向后端开发者,你无需涉足前端各种工具,只需面对浏览器本身,让一切你所需要的元素与交互,从这里信手拈来。
基于Layui编写的一套最简洁、易用的后台框架模板
2、LayUImini又是什么?
LayUImini基于Layui编写的一套最简洁、易用的后台框架模板。 实际上基于LayUI前端框架开发的模板很多,今天就只介绍LayUImini。
主要特性:
- 界面足够简洁清爽,响应式且适配手机端。
- 一个接口几行代码而已直接初始化整个框架,无需复杂操作。
- 页面支持多配色方案,可自行选择喜欢的配色。
- 支持多tab,可以打开多窗口。
- 支持无限级菜单和对font-awesome图标库的完美支持。
- 失效以及报错菜单无法直接打开,并给出弹出层提示完美的线上用户体验。
- url地址hash定位,可以清楚看到当前tab的地址信息。
- 刷新页面会保留当前的窗口,并且会定位当前窗口对应左侧菜单栏。
- 支持font-awesome图标选择插件
下载LayUImini,一般建议下载: iframe版 - v2
( V2版本相比于V1,核心代码进行重构,更加更加规范,配置使用起来也更方便(建议直接使用v2版本)。 iframe版是多标签版本,index.html包含头部、侧边栏、底部等部分, 中间部分通过iframe嵌入子页面,并且可配置是否开启多标签布局,iframe版本功能丰富,是目前常用的后台 布局方式,相比单页面版本更容易上手。)
就像下面这个样子:(是不是很漂亮)
下载iframe版 - v2版本后,我们可以看到非常多的文件。将所有的html文件统一放在templates文件件下,将所有js、css、api、images等都统一的放在static文件下。我这里为了做演示只保留了list.html,其余都删除了。
整体的目录结构
3、建立list.html如下,注意JS和CSS路径
list.html代码如下(示例):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>layui</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="/static/lib/layui-v2.5.5/css/layui.css" media="all">
<link rel="stylesheet" href="/static/css/public.css" media="all">
</head>
<body>
<div class="layuimini-container">
<div class="layuimini-main">
<fieldset class="table-search-fieldset">
<legend>搜索信息</legend>
<div style="margin: 10px 10px 10px 10px">
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">根据ID</label>
<div class="layui-input-inline">
<input type="text" name="id" id="dataRelad" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">地区名字</label>
<div class="layui-input-inline">
<input type="text" name="class_l" id="data_class" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">地区类型</label>
<div class="layui-input-inline">
<input type="text" name="performer" id="data_performer" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">根据标题</label>
<div class="layui-input-inline">
<input type="text" name="title" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-inline">
<button type="submit" class="layui-btn layui-btn-primary" lay-submit lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索</button>
</div>
</div>
</form>
</div>
</fieldset>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-normal layui-btn-sm data-add-btn" lay-event="add"> 添加 </button>
<button class="layui-btn layui-btn-sm layui-btn-danger data-delete-btn" lay-event="delete"> 删除 </button>
</div>
</script>
<table class="layui-hide" id="currentTableId" lay-filter="currentTableFilter"></table>
<script type="text/html" id="currentTableBar">
<a class="layui-btn layui-btn-normal layui-btn-xs data-count-edit" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-xs layui-btn-danger data-count-delete" lay-event="delete">删除</a>
</script>
</div>
</div>
<script src="/static/lib/layui-v2.5.5/layui.js" charset="utf-8"></script>
<script>
layui.use(['form', 'table'], function() {
var $ = layui.jquery,
form = layui.form,
table = layui.table;
table.render({
elem: '#currentTableId',
url: '/item/',//这里要非常注意,要与后端一致。
toolbar: '#toolbarDemo',
defaultToolbar: ['filter', 'exports', 'print', {
title: '提示',
layEvent: 'LAYTABLE_TIPS',
icon: 'layui-icon-tips'
}],
cols: [
[{
type: "checkbox",
width: 50
}, {
field: 'id',
width: 100,
title: 'ID',
sort: true
}, {
field: 'areaName',
width: 300,
title: '地区名字'
}, {
field: 'areaCode',
width: 300,
title: '地区代码',
sort: true
}, {
field: 'pid',
width: 300,
title: '上级区域编码'
}, {
field: 'areaType',
title: '地区类型编码',
minWidth: 300
}, {
title: '操作',
minWidth: 150,
toolbar: '#currentTableBar',
align: "center"
}]
],
limits: [10, 15, 20, 25, 50, 100],
limit: 15,
page: true,
skin: 'line'
});
// 监听搜索操作
form.on('submit(data-search-btn)', function() {
var id = $('#dataRelad').val();
var data_performer = $('#data_performer').val(); //取值
console.log(id);
table.reload('currentTableId', {
method: 'post',
url: '/address_code',
//page: true,
// page: {
// curr: 1
// },
where: {
'id': id,
'data_performer': data_performer //
}
}, );
return false;
});
//执行搜索,表格重载
/**
* toolbar监听事件
*/
table.on('toolbar(currentTableFilter)', function(obj) {
if (obj.event === 'add') { // 监听添加操作
var index = layer.open({
title: '添加用户',
type: 2,
shade: 0.2,
maxmin: true,
shadeClose: true,
area: ['100%', '100%'],
content: '/table/add.html',
});
$(window).on("resize", function() {
layer.full(index);
});
} else if (obj.event === 'delete') { // 监听删除操作
var checkStatus = table.checkStatus('currentTableId'),
data = checkStatus.data;
layer.alert(JSON.stringify(data));
}
});
//监听表格复选框选择
table.on('checkbox(currentTableFilter)', function(obj) {
console.log(obj)
});
table.on('tool(currentTableFilter)', function(obj) {
var data = obj.data;
if (obj.event === 'edit') {
var index = layer.open({
title: '编辑用户',
type: 2,
shade: 0.2,
maxmin: true,
shadeClose: true,
area: ['100%', '100%'],
content: 'table/edit.html',
});
$(window).on("resize", function() {
layer.full(index);
});
return false;
} else if (obj.event === 'delete') {
layer.confirm('真的删除行么', function(index) {
obj.del();
layer.close(index);
});
}
});
});
</script>
</body>
</html>
上述代码下载的地址:https://download.youkuaiyun.com/download/weixin_43354347/17079306(包括html 、 py、电子表格数据等)
注意事项一:html文件放在templates文件下,js等文件放在static文件夹下,这是jinjia2模板的要求。
注意事项二:js代码里面 table.render({
elem: '#currentTableId',
url: '/item/',//这里要非常注意,要与后端请求的地址一致。 后端address_code.py文件里面的@router.get("/item/")