蓝图

蓝图:用于实现单个应用的视图、模板、静态文件的集合。蓝图就是模块化处理的类。

为什么要用蓝图?
随着业务代码的增加,把所有的代码都写进一个程序文件中是非常不合适的,这不仅会让代码阅读变得困难,而且会给后期维护带来麻烦
因此我们需要让代码模块化。根据具体不同功能模块的实现,划分成不同的分类,降低各功能模块之间的耦合度。python中的模块制作和导入就是基于实现功能模块的封装的需求。
然而python中的模块化虽然能把代码给拆分开,但不能解决路由映射的问题

项目搭建

  • 使用蓝图创建项目结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    web
    ├── app
    │   ├── admin
    │   │   ├── __init__.py
    │   │   └── views.py
    │   ├── home
    │   │   ├── __init__.py
    │   │   └── views.py
    │   ├── __init__.py
    │   ├── models.py
    │   ├── static/
    │   └── templates
    │ └── __init__.py
    └── manage.py

    在pycharm里创建普通的python项目,项目名为web;在项目中创建Python文件,名字为manage.py;在项目中创建Python-Package,名字为app;

    在app里创建Python文件,名字为models.py;在app里创建Python-Package,名字为admin;在app里创建Python-Package,名字为home;在app里创建Python-Package,名字为templates;在app里创建Directory,名字为static;

    在admin里创建Python文件,名字为views.py;在home里创建Python文件,名字为views.py;

  • 定义蓝图

    在app/home/init.py文件中输入

    1
    2
    3
    from flask import Blueprint
    home = Blueprint("home",__name__)
    import app.home.views

    在app/admin/init.py文件中输入

    1
    2
    3
    from flask import Blueprint
    admin = Blueprint("admin",__name__)
    import app.admin.views
  • 注册蓝图

    在app/init.py文件中输入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from flask import Flask

    app = Flask(__name__)
    app.debug = True

    from app.home import home as home_blueprint
    from app.admin import admin as admin_blueprint

    #注册蓝图
    app.register_blueprint(home_blueprint)
    app.register_blueprint(admin_blueprint,url_prefix="/admin")
  • 调用蓝图

    在app/home/views.py文件中输入

    1
    2
    3
    4
    from . import home
    @home.route("/")
    def index():
    return "<h1 style='color:green'>this is home</h1>"

    在app/admin/views.py文件中输入

    1
    2
    3
    4
    5
    from . import admin

    @admin.route("/")
    def index():
    return "<h1 style='color:red'>this is admin</h1>"
  • 入口文件

    在app同级目录下的manage.py文件中输入

    1
    2
    3
    4
    from app import app

    if __name__ == "__main__":
    app.run()

图书管理的实现

  • 封装模型,在项目的app下的models.py输入以下内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    # pymysql
    '''
    1,链接mysql数据库
    # 打开数据库连接
    db = pymysql.connect("localhost","testuser","test123","TESTDB" )

    2,创建游标对象
    # 使用 cursor() 方法创建一个游标对象 cursor
    cursor = db.cursor()

    3,执行sql语句
    # 使用 execute() 方法执行 SQL 查询
    cursor.execute("SELECT VERSION()")

    4,返回结果
    fetchone 获取单条结果,
    fetchall 获取所有结果
    rowcount: 这是一个只读属性,并返回执行execute()方法后影响的行数。
    # 使用 fetchone() 方法获取单条数据.
    data = cursor.fetchone()

    5,关闭链接
    # 关闭数据库连接
    db.close()
    '''
    import pymysql

    class Model():
    # 属性
    Mysql_localhost = 'localhost'
    Mysql_username = 'root'
    Mysql_password = '123456'
    Mysql_select_DB = 'wxapp'
    Mysql_charset = 'utf8mb4'
    Mysql_cursorclass=pymysql.cursors.DictCursor
    Mysql_link = ''
    Mysql_cusor = ''

    # 链接数据库
    def __init__(self):
    # 链接mysql
    # 打开数据库连接
    self.Mysql_link = pymysql.connect(self.Mysql_localhost,self.Mysql_username,
    self.Mysql_password,self.Mysql_select_DB,
    charset=self.Mysql_charset,cursorclass=self.Mysql_cursorclass
    )
    # 使用 cursor() 方法创建一个游标对象 cursor
    self.Mysql_cusor = self.Mysql_link.cursor()

    # 查询方法
    def query(self,sql):
    self.Mysql_cusor.execute(sql)
    # 返回查询结果
    return self.Mysql_cusor.fetchall()

    # 执行方法
    def exec(self,sql):
    try:
    self.Mysql_cusor.execute(sql)
    self.Mysql_link.commit()
    # 返回受影响的行数
    num = self.Mysql_cusor.rowcount
    return num
    except:
    # 返回false
    self.Mysql_link.rollback()
    return False

    # 关闭数据库链接
    def __del__(self):
    self.Mysql_link.close()

    # 图书
    '''
    id 书名 title 作者 author 封面图 价格 出版社 数量 书号 内容推荐 作者简介 目录 状态 上架日期
    '''
  • 在app/init.py文件中输入项目文件地址和上传文件地址

    1
    2
    3
    4
    5
    # 上传文件配置
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    # /home/yc/py16/18-flask/web

    app.config['UP_DIR'] = BASE_DIR+'/app/static/uploads/'
  • 添加路由,在app/admin/views.py文件中输入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    from flask import render_template,jsonify,request,url_for
    from app.models import Model
    import time,random,datetime
    from app import app

    # 后台首页
    @admin.route("/")
    def index():
    return render_template('index.html')
    # 图书列表
    @admin.route("/books/index")
    def books_index():
    # 获取当前所有的图书信息
    data = Model().query('select * from books')
    # 加载模板 分配数据
    return render_template('books/index.html',books=data)
    # 图书的添加
    @admin.route('/books/add', methods=['GET', 'POST'])
    def books_add():
    # 判断当前的请求方式
    if request.method == 'GET':
    # 显示添加的表单
    return render_template('books/add.html')
    else:
    # 接受表单数据
    data = request.form.to_dict()
    print(data)

    # 判断是否上传了封面图
    myfile = request.files.get('pic')
    # print(app.config['UP_DIR'])
    if myfile:
    # 执行文件的上传操作
    Suffix = myfile.filename.split('.').pop() # 1.jpg
    filename = str(time.time()) + str(random.randint(10000, 99999)) + '.' + Suffix
    myfile.save(app.config["UP_DIR"] + filename)
    data['pic_url'] = filename

    data['addtime'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    # 执行数据的添加
    sql = '''insert into books values(null,"{title}","{author}","{pic_url}","{price}","{publisher}","{isbn13}","{summary}","{catalog}","{pubdate}","{author_intro}","{status}","{num}","{addtime}")'''.format(**data)
    res = Model().exec(sql)
    if res:
    return '<script>alert("添加成功");location.href="' + url_for('admin.books_index') + '"</script>'

    return '<script>alert("添加失败");location.href="' + url_for('admin.books_add') + '"</script>'
  • 复制静态资源,把模板的asserts文件夹放入static里

  • 在app/templates中创建index.html文件,并输入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    {% block title %}
    <title>Amaze UI Admin index Examples</title>
    {% endblock %}
    <meta name="description" content="这是一个 index 页面">
    <meta name="keywords" content="index">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <link rel="icon" type="image/png" href="/static/assets/i/favicon.png">
    <link rel="apple-touch-icon-precomposed" href="/static/assets/i/app-icon72x72@2x.png">
    <meta name="apple-mobile-web-app-title" content="Amaze UI" />
    <script src="/static/assets/js/echarts.min.js"></script>
    <link rel="stylesheet" href="/static/assets/css/amazeui.min.css" />
    <link rel="stylesheet" href="/static/assets/css/amazeui.datatables.min.css" />
    <link rel="stylesheet" href="/static/assets/css/app.css">
    <script src="/static/assets/js/jquery.min.js"></script>
    </head>
    <body data-type="index">
    <script src="/static/assets/js/theme.js"></script>
    <div class="am-g tpl-g">
    <!-- 头部 -->
    <header>
    <!-- logo -->
    <div class="am-fl tpl-header-logo">
    <a href="javascript:;"><img src="/static/assets/img/logo.png" alt=""></a>
    </div>
    <!-- 右侧内容 -->
    <div class="tpl-header-fluid">
    <!-- 侧边切换 -->
    <div class="am-fl tpl-header-switch-button am-icon-list">
    <span></span>
    </div>
    <!-- 搜索 -->
    <div class="am-fl tpl-header-search">
    <form class="tpl-header-search-form" action="javascript:;">
    <button class="tpl-header-search-btn am-icon-search"></button>
    <input class="tpl-header-search-box" type="text" placeholder="搜索内容...">
    </form>
    </div>
    <!-- 其它功能-->
    <div class="am-fr tpl-header-navbar">
    <ul>
    <!-- 欢迎语 -->
    <li class="am-text-sm tpl-header-navbar-welcome">
    <a href="javascript:;">欢迎你, <span>Amaze UI</span> </a>
    </li>
    <!-- 退出 -->
    <li class="am-text-sm">
    <a href="javascript:;">
    <span class="am-icon-sign-out"></span> 退出
    </a>
    </li>
    </ul>
    </div>
    </div>
    </header>
    <!-- 侧边导航栏 -->
    <div class="left-sidebar">
    <!-- 菜单 -->
    <ul class="sidebar-nav">
    <li class="sidebar-nav-link">
    <a href="{{ url_for('admin.index')}}" class="active">
    <i class="am-icon-home sidebar-nav-link-logo"></i> 首页
    </a>
    </li>
    <li class="sidebar-nav-link">
    <a href="{{ url_for('admin.books_index')}}">
    <i class="am-icon-book sidebar-nav-link-logo"></i>
    图书管理
    </a>
    </li>
    <li class="sidebar-nav-link">
    <a href="">
    <i class="am-icon-table sidebar-nav-link-logo"></i>
    借阅管理
    </a>
    </li>
    <li class="sidebar-nav-link">
    <a href="">
    <i class="am-icon-user sidebar-nav-link-logo"></i>
    用户管理
    </a>
    </li>
    </ul>
    </div>
    <!-- 内容区域 -->
    <div class="tpl-content-wrapper">
    <div class="row-content am-cf">
    {% block con %}
    <div class="row am-cf">
    <div class="am-u-sm-12 am-u-md-12 am-u-lg-4">
    <div class="widget am-cf">
    <div class="widget-head am-cf">
    <div class="widget-title am-fl">月度财务收支计划</div>
    <div class="widget-function am-fr">
    <a href="javascript:;" class="am-icon-cog"></a>
    </div>
    </div>
    <div class="widget-body am-fr">
    <div class="am-fl">
    <div class="widget-fluctuation-period-text">
    ¥61746.45
    <button class="widget-fluctuation-tpl-btn">
    <i class="am-icon-calendar"></i>
    更多月份
    </button>
    </div>
    </div>
    <div class="am-fr am-cf">
    <div class="widget-fluctuation-description-amount text-success" am-cf>
    +¥30420.56
    </div>
    <div class="widget-fluctuation-description-text am-text-right">
    8月份收入
    </div>
    </div>
    </div>
    </div>
    </div>
    <div class="am-u-sm-12 am-u-md-6 am-u-lg-4">
    <div class="widget widget-primary am-cf">
    <div class="widget-statistic-header">
    本季度利润
    </div>
    <div class="widget-statistic-body">
    <div class="widget-statistic-value">
    ¥27,294
    </div>
    <div class="widget-statistic-description">
    本季度比去年多收入 <strong>2593元</strong> 人民币
    </div>
    <span class="widget-statistic-icon am-icon-credit-card-alt"></span>
    </div>
    </div>
    </div>
    <div class="am-u-sm-12 am-u-md-6 am-u-lg-4">
    <div class="widget widget-purple am-cf">
    <div class="widget-statistic-header">
    本季度利润
    </div>
    <div class="widget-statistic-body">
    <div class="widget-statistic-value">
    ¥27,294
    </div>
    <div class="widget-statistic-description">
    本季度比去年多收入 <strong>2593元</strong> 人民币
    </div>
    <span class="widget-statistic-icon am-icon-support"></span>
    </div>
    </div>
    </div>
    </div>
    <div class="row am-cf">
    <div class="am-u-sm-12 am-u-md-8">
    <div class="widget am-cf">
    <div class="widget-head am-cf">
    <div class="widget-title am-fl">月度财务收支计划</div>
    <div class="widget-function am-fr">
    <a href="javascript:;" class="am-icon-cog"></a>
    </div>
    </div>
    <div class="widget-body-md widget-body tpl-amendment-echarts am-fr" id="tpl-echarts">
    </div>
    </div>
    </div>
    <div class="am-u-sm-12 am-u-md-4">
    <div class="widget am-cf">
    <div class="widget-head am-cf">
    <div class="widget-title am-fl">专用服务器负载</div>
    <div class="widget-function am-fr">
    <a href="javascript:;" class="am-icon-cog"></a>
    </div>
    </div>
    <div class="widget-body widget-body-md am-fr">
    <div class="am-progress-title">CPU Load <span class="am-fr am-progress-title-more">28% / 100%</span></div>
    <div class="am-progress">
    <div class="am-progress-bar" style="width: 15%"></div>
    </div>
    <div class="am-progress-title">CPU Load <span class="am-fr am-progress-title-more">28% / 100%</span></div>
    <div class="am-progress">
    <div class="am-progress-bar am-progress-bar-warning" style="width: 75%"></div>
    </div>
    <div class="am-progress-title">CPU Load <span class="am-fr am-progress-title-more">28% / 100%</span></div>
    <div class="am-progress">
    <div class="am-progress-bar am-progress-bar-danger" style="width: 35%"></div>
    </div>
    </div>
    </div>
    </div>
    </div>
    <div class="row am-cf">
    <div class="am-u-sm-12 am-u-md-12 am-u-lg-4 widget-margin-bottom-lg ">
    <div class="tpl-user-card am-text-center widget-body-lg">
    <div class="tpl-user-card-title">
    禁言小张
    </div>
    <div class="achievement-subheading">
    月度最佳员工
    </div>
    <img class="achievement-image" src="/static/assets/img/user07.png" alt="">
    <div class="achievement-description">
    禁言小张在
    <strong>30天内</strong> 禁言了
    <strong>200多</strong>人。
    </div>
    </div>
    </div>
    <div class="am-u-sm-12 am-u-md-12 am-u-lg-8 widget-margin-bottom-lg">
    <div class="widget am-cf widget-body-lg">
    <div class="widget-body am-fr">
    <div class="am-scrollable-horizontal ">
    <table width="100%" class="am-table am-table-compact am-text-nowrap tpl-table-black " id="example-r">
    <thead>
    <tr>
    <th>文章标题</th>
    <th>作者</th>
    <th>时间</th>
    <th>操作</th>
    </tr>
    </thead>
    <tbody>
    <tr class="gradeX">
    <td>新加坡大数据初创公司 Latize 获 150 万美元风险融资</td>
    <td>张鹏飞</td>
    <td>2016-09-26</td>
    <td>
    <div class="tpl-table-black-operation">
    <a href="javascript:;">
    <i class="am-icon-pencil"></i> 编辑
    </a>
    <a href="javascript:;" class="tpl-table-black-operation-del">
    <i class="am-icon-trash"></i> 删除
    </a>
    </div>
    </td>
    </tr>
    <tr class="even gradeC">
    <td>自拍的“政治角色”:观众背对希拉里自拍合影表示“支持”</td>
    <td>天纵之人</td>
    <td>2016-09-26</td>
    <td>
    <div class="tpl-table-black-operation">
    <a href="javascript:;">
    <i class="am-icon-pencil"></i> 编辑
    </a>
    <a href="javascript:;" class="tpl-table-black-operation-del">
    <i class="am-icon-trash"></i> 删除
    </a>
    </div>
    </td>
    </tr>
    <tr class="gradeX">
    <td>关于创新管理,我想和你当面聊聊。</td>
    <td>王宽师</td>
    <td>2016-09-26</td>
    <td>
    <div class="tpl-table-black-operation">
    <a href="javascript:;">
    <i class="am-icon-pencil"></i> 编辑
    </a>
    <a href="javascript:;" class="tpl-table-black-operation-del">
    <i class="am-icon-trash"></i> 删除
    </a>
    </div>
    </td>
    </tr>
    <tr class="even gradeC">
    <td>究竟是趋势带动投资,还是投资引领趋势?</td>
    <td>着迷</td>
    <td>2016-09-26</td>
    <td>
    <div class="tpl-table-black-operation">
    <a href="javascript:;">
    <i class="am-icon-pencil"></i> 编辑
    </a>
    <a href="javascript:;" class="tpl-table-black-operation-del">
    <i class="am-icon-trash"></i> 删除
    </a>
    </div>
    </td>
    </tr>
    <tr class="even gradeC">
    <td>Docker领域再添一员,网易云发布“蜂巢”,加入云计算之争</td>
    <td>醉里挑灯看键</td>
    <td>2016-09-26</td>
    <td>
    <div class="tpl-table-black-operation">
    <a href="javascript:;">
    <i class="am-icon-pencil"></i> 编辑
    </a>
    <a href="javascript:;" class="tpl-table-black-operation-del">
    <i class="am-icon-trash"></i> 删除
    </a>
    </div>
    </td>
    </tr>
    <!-- more data -->
    </tbody>
    </table>
    </div>
    </div>
    </div>

    </div>
    </div>
    {% endblock %}
    </div>
    </div>
    </div>
    </div>
    <script src="/static/assets/js/amazeui.min.js"></script>
    <script src="/static/assets/js/amazeui.datatables.min.js"></script>
    <script src="/static/assets/js/dataTables.responsive.min.js"></script>
    <script src="/static/assets/js/app.js"></script>
    </body>
    </html>
  • 在app/templates中创建books目录,然后在此目录下创建index.html文件,并输入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    {% extends 'index.html' %}
    {% block title %}
    <title>图书列表</title>
    {% endblock %}
    {% block con %}
    <div class="row">
    <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
    <div class="widget am-cf">
    <div class="widget-head am-cf">
    <div class="widget-title am-cf">图书列表</div>
    </div>
    <div class="widget-body am-fr">

    <div class="am-u-sm-12 am-u-md-6 am-u-lg-6">
    <div class="am-form-group">
    <div class="am-btn-toolbar">
    <div class="am-btn-group am-btn-group-xs">
    <a href="{{ url_for('admin.books_add')}}" class="am-btn am-btn-default am-btn-success">
    <span class="am-icon-plus"></span>
    新增
    </a>

    </div>
    </div>
    </div>
    </div>
    <div class="am-u-sm-12 am-u-md-6 am-u-lg-3">
    <div class="am-form-group tpl-table-list-select">
    <select data-am-selected="{btnSize: 'sm'}" style="display: none;">
    <option value="option1">所有类别</option>
    <option value="option2">IT业界</option>
    <option value="option3">数码产品</option>
    <option value="option3">笔记本电脑</option>
    <option value="option3">平板电脑</option>
    <option value="option3">只能手机</option>
    <option value="option3">超极本</option>
    </select>
    </div>
    </div>
    <div class="am-u-sm-12 am-u-md-12 am-u-lg-3">
    <div class="am-input-group am-input-group-sm tpl-form-border-form cl-p">
    <input type="text" class="am-form-field ">
    <span class="am-input-group-btn">
    <button class="am-btn am-btn-default am-btn-success tpl-table-list-field am-icon-search" type="button"></button>
    </span>
    </div>
    </div>
    <div class="am-u-sm-12">
    <table width="100%" class="am-table am-table-compact am-table-striped tpl-table-black ">
    <thead>
    <tr>
    <th>ID</th>
    <th>封面图</th>
    <th>书名</th>
    <th>作者</th>
    <th>价格</th>
    <th>出版社</th>
    <th>出版日期</th>
    <th>书号</th>
    <th>数量</th>
    <th>状态</th>
    <th>录入时间</th>
    <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for v in books%}
    <tr>
    <td class="am-text-middle">{{ v.id }}</td>
    <td>
    <img src="/static/uploads/{{ v.pic_url }}" class="tpl-table-line-img" alt="">
    </td>
    <td class="am-text-middle">{{ v.title }}</td>
    <td class="am-text-middle">{{ v.author }}</td>
    <td class="am-text-middle">{{ v.price }}</td>
    <td class="am-text-middle">{{ v.publisher }}</td>
    <td class="am-text-middle">{{ v.pubdate }}</td>
    <td class="am-text-middle">{{ v.isbn13 }}</td>
    <td class="am-text-middle">{{ v.num }}</td>
    <td class="am-text-middle">
    {% if v.status == 0 %}
    正常
    {% else %}
    下架
    {% endif %}
    </td>
    <td class="am-text-middle">{{ v.addtime }}</td>

    <td class="am-text-middle">
    <div class="tpl-table-black-operation">
    <a href="javascript:;">
    <i class="am-icon-pencil"></i> 编辑
    </a>
    <a href="javascript:;" class="tpl-table-black-operation-del">
    <i class="am-icon-trash"></i> 删除
    </a>
    </div>
    </td>
    </tr>
    {% endfor %}
    <!-- more data -->
    </tbody>
    </table>
    </div>
    <div class="am-u-lg-12 am-cf">
    <div class="am-fr">
    <ul class="am-pagination tpl-pagination">
    <li class="am-disabled"><a href="#">«</a></li>
    <li class="am-active"><a href="#">1</a></li>
    <li><a href="#">2</a></li>
    <li><a href="#">3</a></li>
    <li><a href="#">4</a></li>
    <li><a href="#">5</a></li>
    <li><a href="#">»</a></li>
    </ul>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    {% endblock %}
  • 在app/templates/books下创建add.html文件,并输入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    {% extends 'index.html' %}
    {% block title %}
    <title>图书录入</title>
    {% endblock %}
    {% block con %}
    <div class="row">
    <div class="am-u-sm-12 am-u-md-12 am-u-lg-12">
    <div class="widget am-cf">
    <div class="widget-head am-cf">
    <div class="widget-title am-fl">图书录入</div>
    <div class="widget-function am-fr">
    <a href="javascript:;" class="am-icon-cog"></a>
    </div>
    </div>
    <div class="widget-body am-fr">
    <form action="{{ url_for('admin.books_add')}}" method="POST" enctype="multipart/form-data" class="am-form tpl-form-line-form">
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    书名
    </label>
    <div class="am-u-sm-9">
    <input name="title" required type="text" class="tpl-form-input">
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    作者
    </label>
    <div class="am-u-sm-9">
    <input name="author" required type="text" class="tpl-form-input">
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    出版社
    </label>
    <div class="am-u-sm-9">
    <input name="publisher" required type="text" class="tpl-form-input">
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    价格
    </label>
    <div class="am-u-sm-9">
    <input name="price" required type="text" class="tpl-form-input">
    </div>
    </div>

    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    书号
    </label>
    <div class="am-u-sm-9">
    <input name="isbn13" required maxlength="13" minlength="13" type="text" class="tpl-form-input">
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-weibo" class="am-u-sm-3 am-form-label">
    封面图
    </label>
    <div class="am-u-sm-9">
    <div class="am-form-group am-form-file">
    <div class="tpl-form-file-img">
    <img id="showImg" style="width: 200px;" src="assets/img/a5.png" alt="">
    </div>
    <button type="button" class="am-btn am-btn-danger am-btn-sm">
    <i class="am-icon-cloud-upload"></i> 添加封面图片</button>
    <input id="ReadFile" name="pic" type="file" multiple="">
    </div>
    </div>
    </div>
    <script type="text/javascript">
    $('#ReadFile').change(function(){
    var file = this.files[0];

    //限定上传文件的类型,判断是否是图片类型
    if (!/image\/\w+/.test(file.type)) {
    alert("只能选择图片");
    return false;
    }
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function(e) {
    base64Code = this.result;
    //把得到的base64赋值到img标签显示
    $("#showImg").attr("src", base64Code);
    }
    })
    </script>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    内容推荐
    </label>
    <div class="am-u-sm-9">
    <textarea rows="5" name="summary" placeholder="请输入文章简介"></textarea>
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    作者简介
    </label>
    <div class="am-u-sm-9">
    <textarea rows="5" name="author_intro" placeholder="请输入作者简介"></textarea>
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    目录
    </label>
    <div class="am-u-sm-9">
    <textarea rows="5" name="catalog" placeholder="请输入目录"></textarea>
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    出版日期
    </label>
    <div class="am-u-sm-9">
    <input name="pubdate" type="month" class="tpl-form-input">
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    数量
    </label>
    <div class="am-u-sm-9">
    <input name="num" type="text" class="tpl-form-input">
    </div>
    </div>
    <div class="am-form-group">
    <label for="user-name" class="am-u-sm-3 am-form-label">
    状态
    </label>
    <div class="am-u-sm-9">
    <select name="status" data-am-selected="{searchBox: 1}" style="display: none;">
    <option value="0">立即上架</option>
    <option value="1">录入书库</option>
    </select>
    </div>
    </div>
    <div class="am-form-group">
    <div class="am-u-sm-9 am-u-sm-push-3">
    <button class="am-btn am-btn-primary tpl-btn-bg-color-success ">提交</button>
    </div>
    </div>
    </form>
    </div>
    </div>
    </div>
    </div>
    {% endblock %}