1.安装Flask第三方库
pip3 install Flask
2.创建Flask应用程序
项目结构如上图所示,其中static用来放置静态文件,如js文件、css文件以及图片等,templates文件夹用来放置模板文件,即html文件。
在项目中导入Flask第三方库,使用@app.route()
语句可以设置路由跳转,此语句下面就是Flask服务器接收到该路径访问时会执行的方法,方法名随意,可以不和路径名相同,但是必须要有返回值,返回值可以使html语句,也可以是html文件,浏览器接收返回值并显示在客户端上,从而实现最基础的网络访问。
执行程序:
再打开浏览器,访问提示网址,即127.0.0.1:5000/hello
即实现了最简单基础的网站。
而如果需要返回一个网页的话,可以在templates中创建需要的html网页,再在run.py文件对应的方法中进行返回,返回格式为:
return render_template('index.html')
保存代码,再进行访问原地址即可。
如果出现以下这种异常:
表示找不到模板文件的所在位置,需要在开头进行设置
app = Flask(__name__,template_folder='templates/')
3.寻找满意的HTML模板,将其下载下来,导入到项目中,在其上进行修改,这样比一步一步慢慢写轻松多了,而且也比较美观。
比如模板网站:https://www.webmoban.net/
下载之后进行导入,将css文件放入到/static/css文件夹中,将js文件放入到/static/js文件夹中,将所有的html文件放入到/templates文件中
进行整理之后即可对网站进行优化,但是其中js和css文件导入html文件的方式需要修改一下:
之前的css引入格式:
<link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/bootstrap-responsive.min.css" rel="stylesheet"> <link href="css/site.css" rel="stylesheet">
修改之后的格式:
<link href="{{url_for('static',filename='/css/bootstrap.min.css')}}" rel="stylesheet"> <link href="{{url_for('static',filename='/css/bootstrap-responsive.min.css')}}" rel="stylesheet"> <link href="{{url_for('static',filename='/css/site.css')}}" rel="stylesheet">
同样需要修改js导入格式:
<script src="{{url_for('static',filename='/js/jquery.min.js')}}"></script> <script src="{{url_for('static',filename='/js/bootstrap.min.js')}}"></script> <script src="{{url_for('static',filename='/js/site.js')}}"></script>
这样js文件和css文件都能顺利引入了。
在Flask中,调用render_template来对模版进行渲染,使用render_template,只需要导入这个API就可以,from flask import render_template
而jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用。
模板仅仅是文本文件。它可以生成任何基于文本的格式(HTML、XML、CSV、LaTex 等等)。 它并没有特定的扩展名, .html
或 .xml
都是可以的。
模板包含 变量 或 表达式 ,这两者在模板求值的时候会被替换为值。模板中 还有标签,控制模板的逻辑。
比如在函数中返回一个数值。
@app.route('/hello') def hello(): name = "xiaoming" return render_template('index.html',name=name)
再在html文件中使用jinja2模板语言进行引入与使用,注意使用的是双括号
<body> <h1>{{name}}</h1> </body>
打开浏览器,访问地址
同样可以向html页面传入数组等复杂一些的数据结构,在jinja2模板中也可以使用for语句进行循环或者使用if语句进行逻辑判断。
python
@app.route('/hello') def hello(): num_list = [1,2,3,4,5,6,7,8,9] return render_template('index.html',num_list=num_list)
html
<h1> {% for num in num_list %} {% if num == 5 %} 不显示 {% else %} {{ num }} {% endif %} {% endfor %} </h1>
再访问浏览器地址
注意:使用传递过来的数据使用双括号包裹,但是如果使用if 或 for逻辑语句则需要使用{% %}单括号加百分号进行包裹。并且最后需要使用{% endif %}或{% endfor %}进行结尾。
由于html文件中可能会有很多重复的代码,因此我们可以将重复代码抽离出来,作为模块进行导入与导出。
首先,确定一个文件,在该文件中专门写一些模块,供其他html文件引入调用,比如template-manager.html文件
再进行定义模块,使用macro语句进行包裹
{% macro header(title) %} <meta charset="utf-8"> {% block head %} <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.ico') }}" type="image/x-icon"> {% endblock %} <title>{{title}}</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="{{url_for('static',filename='/js/jquery.js')}}"></script> <script src="{{url_for('static',filename='/js/jquery.masterblaster.js')}}"></script> <link href="{{url_for('static',filename='/css/bootstrap.min.css')}}" rel="stylesheet"> <link href="{{url_for('static',filename='/css/bootstrap-responsive.min.css')}}" rel="stylesheet"> <link href="{{url_for('static',filename='/css/jquery.masterblaster.css')}}" rel="stylesheet"> <link href="{{url_for('static',filename='/css/site.css')}}" rel="stylesheet"> <!--[if lt IE 9]><script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]--> {% endmacro %}
然后在需要的地方引入该文件,使用该模块
在使用之前必须导入,每个文件中只需要导入一次。
{% import 'template-manager.html' as template %}
导入之后就像调用函数一样使用即可。
{{ template.header('Firewise - 主页') }}
注意:引入时使用{%%}进行包裹,使用则就和调用变量一样使用双括号进行包裹,而且可以传递参数。
只需要在@app.route
上面再添加一个路由就可以让多个URL地址对应一个视图函数,如:
@app.route("/",methods=['POST','GET','PUT']) @app.route("/ios/search",methods=['POST','GET','PUT']) def search_crash_ios() :
这样设置访问127.0.0.1:5000和访问127.0.0.1:5000/ios/search都是指向search_crash_ios这个方法。
在HTML中有两种主要的网络请求方式,通过form表单进行请求发起以及通过ajax发起请求。
使用form表单进行请求如下所示:
<form action="/ios/search" method='POST'> <input name="detail" value="detail"></input> </form>
Flask服务器接收请求方式:
@app.route("/ios/search",methods=['POST','GET','PUT']) def search_crash_ios() : # 获取请求数据 detail = request.form['detail'] response = "" # 返回响应数据 return render_template('index.html',response=response)
而使用ajax进行请求如下所示:
$.ajax({ type: 'post', cache: false, dataType: 'json', data: { crash_id: crash_id, crash_remark: detail }, url: "/update/remark", timeout: 3000, success: function(data) { alert("修改成功!") location.reload(); } })
Flask服务器接收请求方式:
@app.route("/update/remark",methods=['POST','GET','PUT']) def update_crash_remark_content() : # 获取请求数据 crash_id = request.form.get('crash_id') crash_remark = request.form.get('crash_remark') response = "" # 返回响应数据 return jsonify({'success':True,'response':response}), 200, {'ContentType':'application/json'}
注意:返回ajax需要导入jsonify,接收html传来的数据需要导入request,即
from flask import Flask,render_template,request,jsonify,current_app
首先将需要设置的图标放入static/img文件夹中,统一取名为favicon.ico,当然也可以取其他名字
再在run.py文件中添加如下方法:
@app.route('/favicon.ico') def favicon(): return current_app.send_static_file('img/favicon.ico')
再在所有html文件的头部添加语句:
{% block head %} <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.ico') }}" type="image/x-icon"> {% endblock %}
保存再刷新页面即可。
Gunicorn是一个unix上被广泛使用的高性能的Python WSGI UNIX HTTP Server。 和大多数的web框架兼容,并具有实现简单,轻量级,高性能等特点。
可以使用Gunicorn+Flask在远端进行部署,也可以使用Nginx+Flask进行部署,也可以选择Gunicorn + Nginx + Flask一起部署。
具体区别如下:
为了简便,而且系统吞吐量也不大,所以暂时使用gunicorn进行部署。
Gunicorn安装
pip3 install gunicorn
再切入到Flask项目的根目录下面,执行以下命令:
gunicorn -w 2 -b 0.0.0.0:8050 run:main
其中 -w 2代表开启两个线程,-b 0.0.0.0:8050表示监听本机8050端口,run:main表示执行Flask项目中的run.py文件中的main方法。
如果想切到后台执行,加一个-D即可,即:
gunicorn -w 2 -b 0.0.0.0:8050 run:main -D
监听端口为8050,所以需要在打开服务器的8050端口,具体命令如下:
sudo firewall-cmd --permanent --add-port=8580/tcp sudo firewall-cmd --reload
终止Gunicorn
首先查看进程,显示主进程id
pstree -ap | grep gunicorn
|-gunicorn,17301 /usr/bin/gunicorn -w 4 app:app --daemon
|-gunicorn,17310 /usr/bin/gunicorn -w 4 app:app --daemon
|-gunicorn,17319 /usr/bin/gunicorn -w 4 app:app --daemon
|-gunicorn,17322 /usr/bin/gunicorn -w 4 app:app --daemon
找到最顶部的进程id,杀掉即可
kill -9 查询出的pid # 这里是17301
如果运行提示失败:
[24890] [ERROR] Connection in use: ('0.0.0.0', 8050)
查看一下占用情况:
netstat -tulpn
杀掉占用端口的进程即可。
如果安装Gunicorn之后,使用gunicorn命令显示找不到命令,即
提示 command not found
可以将将下面的run_gunicorn脚本拷贝到run.py相同目录中:
#-*- coding: utf-8 -*- import re import sys from gunicorn.app.wsgiapp import run if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$','',sys.argv[0]) sys.exit(run())
然后使用这种方法在Flask工程根目录下进行调用Gunicorn
python3 run_gunicorn.py -w 4 -b 0.0.0.0:8050 run:main -D
再访问远端地址即可。