前情提要:
在上一篇中已经完成了一个进阶的helloword,目前目录结构和界面如下,本章节会接着来写,没完成第一章的可以跳转:
结合flask+bootstrap+sklearn从零实现机器学习分类模型的前后端交互网页(一): 介绍、配置及新建项目、helloword_HYQHYQ111的博客-CSDN博客
一、本章内容概述:
在本章中,复现我实现的过程,一开始我看中了bootstrap的巨幕组件,觉得挺好看,就想用用。我计划完成3个页面(不算上弹框),先完成着陆页,布局采用巨幕组件,按钮实现另外两个页面跳转,构建一个基础展示模板,就可以把结构(导航栏、布局、背景图等)复用在另外两个页面啦,通过本章做出来的页面如下:
二、巨幕组件是啥:
- Bootstrap(http://getbootstrap.com/)是Twitter 开发的一个开源框架,它提供的用户界面组件可用于创建整洁且具有吸引力的网页,而且这些网页还能兼容所有现代Web 浏览器。
- 参考bootstrap的官方文档:组件 · Bootstrap v3 中文文档 | Bootstrap 中文网
- 官方示例:
看起来bootstrap提供了一个叫做jumbotron的class,在页面中插入这段代码就可以使用巨幕组件,巨幕适用于需要醒目的标题或介绍,图片元素较少的着陆页,对于当前网页中还挺实用的。
除了巨幕,页面的组成还少了一个导航栏,这里也采用bootstrap提供的导航栏组件实现,按照先完成导航栏,再到巨幕,最后到背景设计的顺序实现。
三、页面设计与实现:
3.1 bootstrap的导入:
1. 安装:
确定了要在网页中引入bootstrap框架,需要完成一点准备工作,即在项目中导入bootstrap,在终端执行【pip install flask_bootstrap】:
pip install flask_bootstrap
2.配置:
Flask 扩展一般都在创建程序实例时初始化,所以我们需要在项目初始化__init__.py文件中插入配置Flask_Bootstrap的初始化代码段,方法如下:
from flask.ext.bootstrap import Bootstrap
bootstrap = Bootstrap(app)
【.vscode/app/__init__.py】更改如下: 增加了两行代码
#项目初始化
from flask import Flask
#导入bootstrap
from flask_bootstrap import Bootstrap
#创建app应用,__name__是python预定义变量,被设置为使用本模块.
app = Flask(__name__)
#初始化Flask_Bootstrap
bootstrap = Bootstrap(app)
#导入路由文件
from app import routes
3.使用:
经过配置Flask-Bootstrap的初始化之后,就可以在程序中使用一个包含所有Bootstrap 文件的基模板。这个模板利用Jinja2 的模板继承机制,让程序扩展一个具有基本页面结构的基模板,其中就有用来引入Bootstrap 的元素。
{%extends "bootstrap/base.html"%}
在base.html中定义了一些块,具体如下:
在用户使用的时候只需要用花括号引入即可,比如使用body这个块,在html中插入的代码如下:
{% block body%}
...(想要在body部分插入的内容)
{% endblock%}
3.2 导航栏的实现:
导航栏在整个页面中起到总览的作用,本项目中使用了反色的导航条,设计了三个页面,因此在导航栏中也有三个标题,在官网介绍中如下:
【.vscode/app/templates/index.html】更改如下:
{%extends "bootstrap/base.html"%}
{%block title %}{{ title }} - 自动分类网页{% endblock %}
{%block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">首页</a></li>
<li><a href="/judge">自动分类页</a></li>
<li><a href="/model">模型标签页</a></li>
</ul>
<ul class="nav navbar-nav navbar-sub pull-right">
<li><a href="/">你好, {{user.username}}</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{%block content %}
{% endblock %}
代码解释说明:
- 第一行 {%extends "bootstrap/base.html"%}中,实现了bootstrap的初始化,在后面的代码中可以直接使用bootstrap
- 第二行,使用title块,并且自定义修改了title
- 第三段,navbar块,这里定义了导航栏,包含两部分:
- 从左到右排列的导航标题,包括"首页"、"自动分类页"、"模型标签页",这里对三个页面的url链接进行了定义。首页默认当前,所以是"/";自动分类页是"/judge";模型标签页是"/model",后续会补充完善
- 最右边的导航标题,用于展现登录的人名,"你好,tomato"(在本项目中人名都默认是tomato,从路由文件中传入的)
- 最后一段空的content块,先用来占位,后续会使用到
运行后,界面如下:
但是因为/judge和/model我们还没有写,因此点击导航栏中 "自动分类页“” 和 "模型标签页" ,页面会报错,不用慌,慢慢完善
3.3 巨幕的结合:
在第二节介绍了巨幕,可以直接把官方提供的代码块加到index.html中,自定义3.2中预留出来的content块
【.vscode/app/templates/index.html】更改如下:
{%extends "bootstrap/base.html"%}
{%block title %}{{ title }} - 自动分类网页{% endblock %}
{%block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">首页</a></li>
<li><a href="/judge">自动分类页</a></li>
<li><a href="/model">模型标签页</a></li>
</ul>
<ul class="nav navbar-nav navbar-sub pull-right">
<li><a href="/">你好, {{user.username}}</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{%block content %}
<div class="jumbotron">
<div class="container">
<h1>欢迎来到自动分类网页!</h1>
<p>当前网页基于机器学习模型,对于输入的数据提供在线自动分类功能,欢迎点击按钮开启分类之旅~</p>
<p><a class="btn btn-primary btn-lg" href="/judge" role="button">尝试自动分类</a>
<a class="btn btn-primary btn-lg" href="/model" role="button">查看模型标签</a>
</p>
</div>
</div>
{% endblock %}
稍微解释下这段代码:
- 在{%block content%}..{%endblock%}直接插入的就是页面的内容部分,这里采用巨幕,也就是class ='jumbotron',所以直接把官方提供的插入到content即可
- 在内容部分加入两个按钮,一个是跳转到自动分类页,一个是跳转到模型标签页
- 按钮部分也是用的bootstap提供的按钮组件,class='btn btn-primary btn-lg',三个关键词分别表示按钮、按钮颜色是默认、按钮大小是大按钮
运行后,界面如下:
同样,因为/judge和/model页面还没写,所以点击按钮跳转会出现404,问题不大,后续慢慢补充。到了这一步,着陆页基本上快完成了,但是想到自动分类页和模型标签页也都需要包含导航栏,为防止代码冗余,以及便于管理,接下来将导航栏部分拆出去做成基础模板,具体在3.4中介绍。
3.4 页面的拆分--基础模板:
很多情况下当页面较多,且页面中会包含一样的组件时,设置一个基础模板是个不错的选择,因此我打算将页面中导航栏部分拆出来,独立成一个html文件,叫做base.html,内容如下:
新建【.vscode/app/templates/base.html】
{%extends "bootstrap/base.html"%}
{%block title %}{{ title }} - 自动分类网页{% endblock %}
{%block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">首页</a></li>
<li><a href="/judge">自动分类页</a></li>
<li><a href="/model">模型标签页</a></li>
</ul>
<ul class="nav navbar-nav navbar-sub pull-right">
<li><a href="/">你好, {{user.username}}</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{%block content %}
{% endblock %}
【.vscode/app/templates/index.html】更改如下:
{%extends "base.html"%}
{%block content %}
<div class="jumbotron">
<div class="container">
<h1>欢迎来到自动分类网页!</h1>
<p>当前网页基于机器学习模型,对于输入的数据提供在线自动分类功能,欢迎点击按钮开启分类之旅~</p>
<p><a class="btn btn-primary btn-lg" href="/judge" role="button">尝试自动分类</a>
<a class="btn btn-primary btn-lg" href="/model" role="button">查看模型标签</a>
</p>
</div>
</div>
{% endblock %}
经过拆分后运行,界面没有变化
3.5 页面跳转和路由配置:
接下来完成两个子页面的基本设置、实现页面跳转,以及完成路由的配置。
新建【.vscode/app/templates/judge.html】
{%extends "base.html"%}
{%block content %}
<div class="container">
<h1>这是自动分类页</h1>
</div>
{% endblock %}
新建【.vscode/app/templates/model.html】
{%extends "base.html"%}
{%block content %}
<div class="container">
<h1>这是模型标签页</h1>
</div>
{% endblock %}
修改路由文件【.vscode/app/routes.py】
#主页路由
#从app模块中即从__init__.py中导入创建的app应用
from app import app
from flask import render_template
#建立路由,通过路由找到覆盖的方法,可以多个路由指向同一个方法
@app.route('/')
@app.route('/index')
def index():
#首页显示的数据如下
user = {'username':'tomato'}
#将需要展示的数据传递给模板进行展示
return render_template('index.html',title ='tomato的',user= user)
@app.route('/judge')
def judge():
#首页显示的数据如下
user = {'username':'tomato'}
#将需要展示的数据传递给模板进行展示
return render_template('judge.html',title ='tomato的',user= user)
@app.route('/model')
def model():
#首页显示的数据如下
user = {'username':'tomato'}
#将需要展示的数据传递给模板进行展示
return render_template('model.html',title ='tomato的',user= user)
运行后界面如下:
3.6 背景图片的选取及设置:
当前页面还是显得有点单调,在这对页面背景进行统一设置,先去网上选取好看的背景,这里取自【4K影视壁纸_高清4K影视图片_彼岸图网】【自然风景摄影图横向-千库网】,下载下来。在项目的app文件夹中新建一个static文件夹,专门用于存放图片,将下载后的图片拖入文件夹,取名为home.jpg:
接下来配置这张图片为背景图,首先需要更改的是base.html,更改背景的方式有很多,这里使用css,在body块中插入<style>标签,里面自定义mybkg 和 container 两个class,一个作用于网页的背景区域,设定背景图,定位,尺寸等,另一个作用于全部container,设定内容部分包含的范围。
【.vscode/app/templates/base.html】更改如下:
{%extends "bootstrap/base.html"%}
{%block title %}{{ title }} - 自动分类网页{% endblock %}
{%block body%}
<style>
.mybkg {
background-image: url(../static/home.jpg);
background-position: right bottom, left top;
background-repeat: no-repeat, repeat;
background-size:100% 100%;
height: 700px;
}
.container {
height: 100%;
margin-top:0;
margin-bottom: 0;
}
</style>
{%block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">首页</a></li>
<li><a href="/judge">自动分类页</a></li>
<li><a href="/model">模型标签页</a></li>
</ul>
<ul class="nav navbar-nav navbar-sub pull-right">
<li><a href="/">你好, {{user.username}}</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{%block content %}
{% endblock %}
{% endblock %}
接着更改三个页面,用mybkg包含,分别如下:
【.vscode/app/templates/index.html】更改如下:
{%extends "base.html"%}
{%block content %}
<div class ='mybkg'>
<div class="jumbotron">
<div class="container">
<h1>欢迎来到自动分类网页!</h1>
<p>当前网页基于机器学习模型,对于输入的数据提供在线自动分类功能,欢迎点击按钮开启分类之旅~</p>
<p><a class="btn btn-primary btn-lg" href="/judge" role="button">尝试自动分类</a>
<a class="btn btn-primary btn-lg" href="/model" role="button">查看模型标签</a>
</p>
</div>
</div>
<div>
{% endblock %}
【.vscode/app/templates/judge.html】更改如下:
{%extends "base.html"%}
{%block content %}
<div class ='mybkg'>
<div class="container">
<h1>这是自动分类页</h1>
</div>
</div>
{% endblock %}
【.vscode/app/templates/model.html】更改如下:
{%extends "base.html"%}
{%block content %}
<div class ='mybkg'>
<div class="container">
<h1>这是模型标签页</h1>
</div>
</div>
{% endblock %}
3.7 效果:
经过以上的更改后,运行后,三个页面展示如下:
四、遇到的问题和解决:
- 导航栏最右边的用户信息文字显示问题:
- 右边文字一开始采用<p>标签来展示,但是发现和左边导航存在位置和颜色的偏差,所以最后还是采用<a href>链接的形式展示(虽然并没有跳转)
- 巨幕组件引入后,按钮大小有问题:
- 按钮这一块,本来想用自己定义的按钮样式来完成,但是没想到bootstrap提供的组件太强大了,很难进行更改,最后按照官方提供的按钮样式更改class后完成
- 背景插入后不显示:
- 这一块也是我花费了比较长时间的部分,一开始设置的背景就像被吞了一样,什么都没有,先查看了插入图片的url是不是写错了,没问题后在查看插入图片的方式,这里还真的需要对背景的位置和大小进行设置,不然会找不到
- 页面跳转问题:
- 页面写好后,一定要更改路由文件,进行相应的跳转配置,否则页面以及找不到
五、总结:
经过本章节后已经基本完成了首页,以及三个页面之间的跳转,设置了基础模板页,后续会接着在里面添加内容,甚至包括js响应函数的配置,总结下目前的目录结构如下:
在下一篇中将完成自动分类页面,该页面中包括一个提交表单,提交和查看两个按钮,在后端训练一个机器学习分类模型,并且把模型保存以及调用,最后完成从后端拿到分类结果后返回给前端展示,实现前后端的初级联动。
写文章不易,你的点赞评论转发收藏是我前进的动力~