flask做web基础
#参考
https://www.jianshu.com/p/6452596c4edb
#中文手册 http://docs.jinkan.org/docs/flask/quickstart.html http://docs.jinkan.org/docs/flask/index.html
w3cschool: https://www.w3cschool.cn/flask/
flask是python的一个web微框架 做演示demo/或者简单网页工具十分方便
安装flask:pip install flask
用来做一个正式网站还是需要配置良好的目录结构
flask-demo/
├ run.py # 应用启动程序
├ config.py # 环境配置
├ requirements.txt # 列出应用程序依赖的所有Python包
├ tests/ # 测试代码包
│ ├ __init__.py
│ └ test_*.py # 测试用例
└ myapp/
├ admin/ # 蓝图目录
├ static/
│ ├ css/ # css文件目录
│ ├ img/ # 图片文件目录
│ └ js/ # js文件目录
├ templates/ # 模板文件目录
├ __init__.py
├ forms.py # 存放所有表单,如果多,将其变为一个包
├ models.py # 存放所有数据模型,如果多,将其变为一个包
└ views.py # 存放所有视图函数,如果多,将其变为一个包
最简单测试:test.py
python test.py 后,浏览器输入localhost:5000就能看到网页显示Hello world。 或者输入:127.0.0.1:5000
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World'
if __name__ == '__main__':
app.debug = True # 设置调试模式,生产模式的时候要关掉debug
app.run()
Jinja2是一个广泛应用的模板引擎,可以很方便的把数据嵌入到网页问价中
from flask import Flask
from flask import render_template
app = Flask(__name__)
@app.route('/hello')
@app.route('/hello/<name>')
def hello(name=None):
#渲染hello.html模板,把name数据传入进去
return render_template('hello.html', name=name)
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
#模版文件:hello.html ”http://localhost:5000/hello/world”
<!doctype html>
<title>Hello Sample</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
#模板继承 #father.html
<!doctype html>
<title>Hello Sample</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
<div class="page">
{% block body %}
{% endblock %}
</div>
#继承上面模板
{% extends "father.html" %}
{% block body %}
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
{% endblock %}
会话session 记录已登录信息,避免重复进入登录页面
from flask import Flask,url_for,request,render_template,redirect,session
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
if request.form['user'] == 'admin':
session['user'] = request.form['user']
return 'Admin login successfully!'
else:
return 'No such user!'
if 'user' in session:
return 'Hello %s!' % session['user']
else:
title = request.args.get('title', 'Default')
return render_template('login.html', title=title)
@app.route('/logout')
def logout():
session.pop('user', None)
return redirect(url_for('login'))
app.secret_key = '123456'
if __name__ == "__main__":
app.run(debug=True)
使用Cookie
from flask import Flask,url_for,request,render_template,redirect,session,make_response
import time
@app.route('/login', methods=['POST', 'GET'])
def login():
response = None
if request.method == 'POST':
if request.form['user'] == 'admin':
session['user'] = request.form['user']
response = make_response('Admin login successfully!')
#设置Cookie,保存在浏览器中,第三个参数max_age设置有效期(秒),不设置则浏览器关闭后失效
response.set_cookie('login_time', time.strftime('%Y-%m-%d %H:%M:%S'))
...
else:
if 'user' in session:
#”request.cookies”对象就是一个保存了浏览器Cookie的字典,使用其”get()”函数就可以获取相应的键值。
login_time = request.cookies.get('login_time')
response = make_response('Hello %s, you logged in on %s' % (session['user'], login_time))
...
return response
app.secret_key = '123456' #设置秘钥,最好使用随机
if __name__ == "__main__":
app.run(debug=True)
错误处理
from flask import Flask,abort
app = Flask(__name__)
@app.route('/error')
def error():
abort(404) #直接退出
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404 #返回重写的错误页面
if __name__ == "__main__":
app.run(debug=True)
URL重定向:
#不带/时,Flask会自动重定向到正确地址。
@app.route('/projects/')
def projects():
return 'The project page'
#末尾带上/后Flask会直接报404 NOT FOUND错误
@app.route('/about')
def about():
return 'The about page'
---------------------------------------------
from flask import session, redirect
@app.route('/')
def index():
if 'user' in session:
return 'Hello %s!' % session['user']
else:
#redirect()”函数当客户端浏览某个网址时,将其导向到另一个网址
#“redirect()”的第二个参数时HTTP状态码,可取的值有301, 302, 303, 305和307,默认即302
return redirect(url_for('login'), 302)
#上传文件 #werkzeug 判断文件名是否安全 pip install werkzeug #服务端:
from flask import Flask, request
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
#配置信息 上传目录
app.config['UPLOAD_FOLDER'] = 'static/uploads/'
#控制上传文件的大小
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 #16MB
#上传文件格式,后缀名
app.config['ALLOWED_EXTENSIONS'] = set(['png', 'jpg', 'jpeg', 'gif'])
# For a given file, return whether it's an allowed type or not
def allowed_file(filename):
return '.' in filename and
filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']
@app.route('/')
def hello_world():
return 'hello world'
@app.route('/upload', methods=['POST'])
def upload():
upload_file = request.files['image01']#图片以"image01"标识
file_content = request.files['image01'].stream.read()#获取上传文件的内容
if upload_file and allowed_file(upload_file.filename):
filename = secure_filename(upload_file.filename)
#路径
upload_file.save(os.path.join(app.root_path, app.config['UPLOAD_FOLDER'], filename))
return 'hello, '+request.form.get('name', 'little apple')+'. success'
else:
return 'hello, '+request.form.get('name', 'little apple')+'. failed'
if __name__ == '__main__':
app.run(debug=True)
客户端
import requests
#当前目录下的 01.jpg上传到服务器
files = {'image01': open('01.jpg', 'rb')}
user_info = {'name': 'letian'}
r = requests.post("http://127.0.0.1:5000/upload", data=user_info, files=files)
#coding=utf-8
from flask import Flask
from flask import request
app = Flask(__name__)
#路由 是指url/register只接受POST方法。也可以根据需要修改methods参数
@app.route("/login", methods=["GET", "POST"])
def hello_str():
if request.method == "POST":
print(request.headers) #请求头
#多种接收数据方法
username = request.form['username']
username = request.form.get("username",type = str,default="admin") #获取表单数据
#对应请求requests.post(url, json.dumps(params)) as_text=True 变成Unicode 使用 json.loads()转换字典
params = request.get_data(as_text=True)
params = request.get_json()
params = request.data
elif request.method == "GET":
username = request.args.get("username") #获取get请求参数
username = request.values.get("username") #获取所有有请求参数
return redirect(url_for('home',username=request.form['username']))
@app.route('/home')
def home():
return render_template('home.html', username=request.args.get('username'))
if __name__ == "__main__":
#要控制上产文件的大小,可以设置请求实体的大小,文件
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 #16MB
app.debug = True
app.run('0.0.0.0',80)
#post 请求
import requests, json user_info = {'name': 'letian'}
headers = {'content-type': 'application/json'}
r = requests.post("http://127.0.0.1:5000/json", data=json.dumps(user_info), headers=headers)
print r.headers
print r.json()
构建相应 自己设置相应参数返回
from flask import Flask,url_for,request,render_template,redirect,session,make_response
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
...
if 'user' in session:
...
else:
title = request.args.get('title', 'Default')
response = make_response(render_template('login.html', title=title), 200)
response.headers['key'] = 'value'
return response
if __name__ == "__main__":
app.run(debug=True)
request相关属性
form 接收POST/PUT请求数据,MultiDict
arges MultiDict如searchword = request.args.get('key', '')
values 可以代替form和args
cookies 请求的cookies,类型是dict
headers 请求头,类型是dict
data 包含请求的数据,转为字符串,处理不了mimetype
files MultiDict,带有POST/PUT请求上传的文件
environ WSGI环境配置
method 请求方法,如GET,POST
path 获取请求文件路径
base_url 获取域名与请求文件路径
url 获取全部url
url_root 获取域名
blueprint 蓝图名字
endpoint endpoint匹配请求
json 如果mimetype是application/json,会解析json,不是则返回None,可替代get_json()
max_content_length 返回MAX_CONTENT_LENGTH的配置键
view_args = None 一个匹配请求的view参数的字典,当匹配的时候发生异常,会返回None。
get_json(force=False, silent=False, cache=True)
下面的应该用不到,搬运过来
on_json_loading_failed(e)
module 如果请求是发送到一个实际的模块,则该参数返回当前模块的名称。这是弃用的功能,使用blueprints替代。
routing_exception = None 如果匹配URL失败,这个异常将会/已经抛出作为请求处理的一部分。这通常用于NotFound异常或类似的情况。
url_rule = None 内部规则匹配请求的URL。这可用于在URL之前/之后检查方法是否允许(request.url_rule.methods) 等等。
默认情况下,在处理请求函数中写下 print('request.url_rule.methods', request.url_rule.methods)
会打印:
request.url_rule.methods {‘GET’, ‘OPTIONS’, ‘HEAD’}
原文地址:https://www.cnblogs.com/vwvwvwgwgvervae/p/12993904.html
- 简单易学的机器学习算法——线性支持向量机
- Java设计模式-模板方式模式
- 由一条create语句的问题对比mysql和oracle中的date差别 (r7笔记第26天)
- Java设计模式-命令模式
- 关于执行计划中的%CPU的含义 (r7笔记第25天)
- Java设计模式-享元模式
- 简单易学的机器学习算法——线性可分支持向量机
- 基于gensim的Doc2Vec简析,以及用python 实现简要代码
- 关于db link权限分配的苦旅(一) (r7笔记第42天)
- Java设计模式-责任链模式
- Java设计模式-策略模式
- CPU 100%负载的性能优化分析(r7笔记第40天)
- Sklearn-train_test_split随机划分训练集和测试集
- 使用shell来定制dbms_sqltune(r7笔记第39天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- AntUI卡片Cards
- AntUI常规Forms表单
- 二叉树:看看这些树的最大深度
- C++核心准则SF.5: .cpp文件必须包含定义它接口的.h文件
- C++核心准则SF.6:(只)为转换,基础库或在局部作用域内部使用using namspace指令
- C++核心准则SF.7:不要在头文件中的全局作用域中使用using namespace指令
- 二叉树:看看这些树的最小深度
- Hive初体验
- Hive数据的存储以及在centos7下进行Mysql的安装
- 一个改进的数学学习工具
- 配置hive的元数据到Mysql中
- 二叉树:我有多少个节点?
- POST请求和GET请求如何传递和接收解析参数
- 二叉树:我平衡么?
- 机器学习中的常用编码方式(二)