Flask异步渲染管理后台局部页面

想法 / One simple idea

最近在折腾研究Python Web开发,入坑了Flask,用习惯Python了发现用它干啥都是~真香!
试着写了个考试管理的后台,以前做web开发的套路,管理后台用传统的iFrame来加载和切换不同功能页面,感觉很low,完全无法愉快的装X啊~之前看过一篇用Flask+VUE做单页面应用的教程(传送门),也感受过了VUE的魅力,各种双向绑定6的飞起,不过像我这种泥腿子开发而言,还是有点复杂了,套路太深,还是想想怎么用好Python原生的Flask轮子来搞吧.研究了半天Jinja模板的用法,配上ajax异步获取局部页面的HTML数据,搞起来也是挺方便的.
好了,想法啰嗦完毕,开始进入正题!

实现效果

在这里插入图片描述

文件结构

.
├── app.py		# Flask主程序入口
├── static		# 静态调用文件
│   ├── css
│   ├── img
│   ├── js
│   └── vendor
└── templates	# 模板
    ├── admin		# 后台模板
    │   ├── admin.html
    │   ├── admin_base.html
    │   ├── dashboard.html
    │   └── detail.html
    ├── base.html	# 下面这些是首页相关模板,请忽视
    ├── index.html
    ├── index2.html
    └── login.html

补充一下,后台使用了SBAdmin2模板,传送门在此
吐槽一下,这货是Start Bootstrap的缩写,真是够SB的了,哈哈~

Flask后台代码

添加路由/admin获取GET方式传入的type变量,根据变量内容输出不同内容渲染的HTML代码
render_template函数返回的值其实就是HTML文本数据,可以直接用在后面使用ajax异步调用

"""Flask主程序

Returns:
    [type] -- [description]
"""
from flask import Flask, request, render_template
from flask_cors import CORS

DEBUG = False
TEMPLATES_AUTO_RELOAD = True
JSON_AS_ASCII = False

app = Flask(__name__)
app.config.from_object(__name__)
CORS(app)

@app.route('/admin', methods=['GET'])
def admin():
    """后台管理获取局部渲染HTML数据
    """
    data = request.values
    if data['type'] == 'dashboard':
        return render_template('/admin/dashboard.html')
    if data['type'] == 'detail':
        return render_template('/admin/detail.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0')

模板

admin_base.html

就是正常的HTML,这里主要是需要用到Flask内置的jinja2模板语法中的模板块{% block body %}{% endblock %}其中的body和script是自己起的块名称,可以自行修改,该模板作为基础模板,其中设置的两个块会在后面的其他模板继承的时候进行填充.
【划重点】
引用静态的css和js文件需要使用/static/内置的路径变量

<!DOCTYPE html>
<html lang="en" class="h-100">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文明单位测试平台-管理后台</title>
    <link href="/static/css/sb-admin-2.min.css" rel="stylesheet">
    <link href="/static/css/lian.css" rel="stylesheet">
</head>

<body id="page-top" data-gr-c-s-loaded='true'>
    {% block body %}{% endblock %}
</body>
<script src="/static/vendor/jquery/jquery.min.js"></script>
<script src="/static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="/static/vendor/jquery-easing/jquery.easing.min.js"></script>
<script src="/static/js/sb-admin-2.min.js"></script>
<script src="/static/js/echarts.min.js"></script>
{% block script %}{% endblock %}

</html>

admin.html

注意开头的{% extends "/admin/admin_base.html" %}声明了该模板是从admin_base.html继承而来,下面分别对基础模板中挖的两个坑body和script块进行了内容的填充.
自定义的getContent(type)函数用于点击菜单栏中项目进行异步加载页面主体区域内容,这里需要注意$.ajax函数中的dataType参数需要设置为html

{% extends "/admin/admin_base.html" %}
{% block body %}

<div id="wrapper">

    <!-- 左侧菜单栏 -->
    <ul class="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion" id="accordionSidebar">

        <!-- 左侧菜单栏 - 标题 -->
        <a class="sidebar-brand d-flex align-items-center justify-content-center">
            <div class="sidebar-brand-text mx-3">考试管理后台</div>
        </a>

        <!-- 分割线 -->
        <hr class="sidebar-divider my-0">

        <!-- 导航菜单项目 - 状态总览 -->
        <li class="nav-item active">
            <a class="nav-link" href="#" onclick="getContent('dashboard')">
                <span>状态总览</span></a>
        </li>

        <!-- 分割线 -->
        <hr class="sidebar-divider">

        <!-- 分组标题 -->
        <div class="sidebar-heading">
            成绩查看
        </div>

        <!-- 导航菜单项目 - 单人成绩 -->
        <li class="nav-item">
            <a class="nav-link" href="#" onclick="getContent('detail')">
                <span>单人成绩</span></a>
        </li>


    </ul>
    <!-- 左侧菜单栏结束 -->

    <!-- 右侧主体层 -->
    <div id="content-wrapper" class="d-flex flex-column">

        <!-- 主体层 -->
        <div id="content">

            <!-- 顶部工具栏 -->
            <nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
                <ul class="navbar-nav">
                    <p>这里是顶部工具栏</p>
                </ul>
            </nav>
            <!-- 顶部工具栏结束 -->

            <!-- 主体内容区域 -->
            <div class="container-fluid" id="main">

                <div class="jumbotron">
                    <h1>这里是默认显示的主体内容区域</h1>
                </div>

            </div>
            <!-- 主体内容区域结束 -->

        </div>
        <!-- 主体层结束 -->

        <!-- Footer -->
        <footer class="sticky-footer bg-white">
            <div class="container my-auto">
                <div class="copyright text-center my-auto">
                    <span>Copyright © 这里是Footer底部版权栏</span>
                </div>
            </div>
        </footer>
        <!-- End of Footer -->

    </div>
    <!-- 右侧主体层结束 -->

</div>
{% endblock %}
{% block script %}
<script>
    // 通过type变量选择要获取的渲染内容
    function getContent(type) {
        $.ajax({
            type: 'GET',
            url: '/admin',
            data: { 'type': type },
            dataType: 'html',
            success: function (data) {
                $("#main").html(data);
            }
        });
    }
</script>
{% endblock %}

dashboard.html & detail.html

这里就不上代码了,就是用在使用ajax异步从/admin地址处获取到的HTML内容

发布了181 篇原创文章 · 获赞 82 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/lpwmm/article/details/102708738