python之框架篇(Flask)
1、linux下创建虚拟环境
virtualenv
1.安装 pip3 install virtualenv 2.创建虚拟环境 virtualenv —no-site-packages —python=python3 env1 3.激活虚拟环境 sourcce /opt/MyVirtualenv/venvDjango1/bin/activate 4.测试 python3 或者 pip3 list
virtualenvwrapper
1.安装virtualenvwrapper工具 pip3 install virtualenvwrapper 2.配置环境变量每次开机就加载virtualenvwrapper 配置步骤: 1.打开个人用户配置文件 vim ~/.bashrc 光标定位到最后空白行 2.添加环境变量 ,注意是四个配置,保证路径和你自己机器一样 export WORKON_HOME=~/Envs/ #设置virtualenv的统一管理目录 export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages' #添加virtualenvwrapper的参数,生成干净隔绝的环境 export VIRTUALENVWRAPPER_PYTHON=/opt/python36/bin/python3 #指定python3本体解释器 source /opt/python36/bin/virtualenvwrapper.sh #执行virtualenvwrapper安装脚本 3.复制如上配置,写入到,~/.bashrc 个人配置文件中,每次登陆就加载 4.退出当前回话,重新登陆,加载 虚拟环境工具 5.学习 虚拟环境工具的命令 创建一个虚拟环境: $ mkvirtualenv myproject 这会在 ~/Envs 中创建 myproject 文件夹 激活虚拟环境: workon myproject 切换虚拟环境: workon myproject 退出虚拟环境: deactivate 删除虚拟环境,需要先退出虚拟环境: rmvirtualenv myproject
2、windows下
1.创建一个最简单的flask项目(pipenv)
#1、新建虚拟环境 #新建一个文件夹,进入文件夹。shift+右键打开命令窗口 pip install pipenv#此处使用pipenv创建虚拟环境 pipenv install pipenv shell pipenv install flask #查看包依赖关系: pipenv graph #查看虚拟环境安装目录 pipenv --venv #打开pycharm》open》选择项目文件夹
#2、创建项目 #项目目录下新建app.py文件,写入以下代码: from flask import Flask # 从flask模块中引出类 Flask app = Flask(__name__) # 实例化Flask类 app @app.route('/') # 声明一个路由地址 def index(): return 'hello oldboy !' if __name__ == '__main__': app.run()#默认是运行在 http://127.0.0.1:5000/
#3、运行 #运行app.py文件,命令行使用python app.py或者pycharm中直接运行app.py文件 #浏览器输出 http://127.0.0.1:5000/ 页面显示 hello oldboy !
2.virtualenv创建方式(virtualenv )
#1、新建虚拟环境 #新建一个文件夹,进入文件夹。shift+右键打开命令窗口 pip install virtualenv#此处使用virtualenv创建虚拟环境 virtualenv mysite#项目名 pip install flask virtualenv --venv #查看虚拟环境目录 #打开pycharm》open》选择项目文件夹 #2、创建项目 #项目目录下新建app.py文件,写入以下代码: from flask import Flask # 从flask模块中引出类 Flask app = Flask(__name__) # 实例化Flask类 app @app.route('/') # 声明一个路由地址 def index(): return 'hello oldboy !' if __name__ == '__main__': app.run()#默认是运行在 http://127.0.0.1:5000/ #3、运行 #运行app.py文件,命令行使用python app.py或者pycharm中直接运行app.py文件 #浏览器输出 http://127.0.0.1:5000/ 页面显示 hello oldboy !
3、直接利用pycharm创建
打开新项目后,配置interpreter,安装flask,后续启动方式与以上两种方式相同
4、初始项目示例代码
from flask import Flask, views from flask_session import Session app=Flask(__name__) Session(app) app.secret_key='ankjfbab' class Login(views.MethodView): def get(self): return 'return 方法' app.add_url_rule('/login',endpoint=None,view_func=Login.as_view(name='login')) if __name__== "__main__": app.run("0.0.0.0",5001)
#app下的__init__文件中 from flask import Flask from app.views import auth from app.settings import DebugConfig def create_app(): app = Flask(__name__) app.config.from_object(DebugConfig) app.register_blueprint(auth.index) app.register_blueprint(auth.login) return app #views中的auth文件中 from flask import Flask,redirect,Blueprint index=Blueprint('index',__name__) login=Blueprint('login',__name__) @index.before_request def mysession(): if session.get('user'): return None else: return redirect('/login') #settings配置文件中 class DebugConfig(object): DEBUG=True # SECRET_KEY='ankdajfbab' #项目启动文件中 from apptoy import create_app app = create_app() @app.errorhandler(404) def errors(status): return '请核对您的url,确保正确!' if __name__ == '__main__': app.run()
1、文件配置
一般将配置文件写两个,一个secure(放置机密配置),一个settings(放置一般配置),以下演示代码未区分
class DebugConfig(object): DEBUG=True SECRET_KEY = "@#$%^&*(" SESSION_COOKIE_NAME = "赵丽颖" class TestingConfig(object): TESING=True SECRET_KEY = "%^^T*I*H%^F%$R*$E%H(O^&^%GI*^%&RG" SESSION_COOKIE_NAME = "834473503"
#项目启动文件中: app = Flask(__name__, template_folder="tem", static_folder="sta", static_url_path="/static") app.config.from_object(DebugConfig) app.register_blueprint(users.user) if __name__ == '__main__': app.run()
2、使用app.config配置(可通过查看app.default_config的源码确定有哪些配置项)
#创建完app之后 app01.config["DEBUG"] = True app01.config["SECRET_KEY"] = "@#$%^&*" app01.config["SESSION_COOKIE_NAME"] = "赵丽颖" app01.config["JSONIFY_MIMETYPE"] = "video/mp4"
#蓝图文件中 from flask import Blueprint user = Blueprint("user",__name__,url_prefix="/user_bp") @user.route("/user",methods=["GET","POST"]) def user_func(): return "I am user Blueprint" #app启动文件中 from other import user app = Flask(__name__, template_folder="tem", static_folder="sta", static_url_path="/static") app.register_blueprint(users.user)
一个app中只创建一个蓝图的规范下
#应用文件夹下的__init__中 from flask import Blueprint admin=Blueprint('admin',__name__) from app.controller import user from app.controller import login #app创建文件中 from flask import Flask from app.config import secure from app.controller import admin def create_app(): app=Flask(__name__) app.config.from_object(secure) app.register_blueprint(admin) return app
1、request
1.request的常用成员
1.scheme : 获取请求方案(协议)
2.method : 获取本期请求的请求方式(重点)
3.args : 获取使用get请求方式提交的数据
4.form : 获取使用post请求方式提交的数据
5.cookies : 获取 cookies 的相关信息
6.headers : 获取 请求消息头 的相关信息
7.files : 获取上传的文件
8.path : 获取请求的url地址(进入到主机后的请求资源地址,不包含请求参数)
9.full_path : 获取请求的url地址(进入到主机后的请求资源地址,包含请求参数)
10.url : 获取完整的请求地址,从协议开始的地址
2.获取请求提交的数据
1.get 请求方式
1.表单允许实现get请求
<form action="" method="get">
姓名:<input name="uname">
</form>
2.在请求地址后拼请求提交的参数
http://localhost:5000/06-get?uname=xxx&upwd=xxx
获取 get 请求方式提交的数据 :
request.args 封装的是get请求的数据
2.post 请求方式
post请求只有在表单中才能够被触发
<form method="post">
获取 post 请求提交的数据 :
request.form 封装的就是 post 请求的数据,类型为字典
request.form['name'] : 获取 name 对应的值
request.form.get('name') : 获取 name 对应的值
request.form.getlist('name') : 获取 name 列表数据(如复选框,下拉列表)
from flask import Flask,render_template,redirect,send_file,jsonify,request app = Flask(__name__) @app.route("/req",methods=["POST","GET"]) def req(): print(request.method) print(request.url) print(request.cookies) print(request.path) print(request.args) print(request.args.get("id")) print(request.args["name"]) print(request.args.to_dict()) print(request.form) print(request.form.get("username")) try: print(request.form["usernae"]) except KeyError: print("没有这个Key") except AttributeError: print("没有这个Attr") print(request.form.to_dict()) my_file = request.files.get("my_file") import os file_path = os.path.join("static","1.jpg") my_file.save(file_path) print(json.loads(request.data)) # b"" # 存放的是请求体中的原始信息 Content-Type:asdfkjashgjvajhgjkow print(request.json.get("key")) # None # 请求头中存在 Content-Type:application/json 将请求体中的数据 存放在JSON中 print(request.values) # 坑 return "hello!!!" app.run(debug=True)
#request代码集合 if request.method=='POST': if request.form.get('username')==user:
#获取并保存文件 ret=request.files.get('filename') file_path=os.path.join('static','001.jpg') ret.save(file_path)
req_info = request.form.to_dict()
user_socket = request.environ.get("wsgi.websocket") # type:WebSocket
2、response
一共有:return "普通字符串",render_template,redirect,send_file,jsonify五种方式
1.什么是响应
响应就是由服务器端带给客户端的内容,对应着请求。
响应可以是普通的字符串,模板 或 重定向
return "普通字符串"
return render_template('xxx.html')
2.响应对象
响应对象:将响应的内容封装到一个对象中,可以完成更多的响应的行为(如cookies,...)
在Flask中,使用 make_response() 构建响应对象
from flask import make_response
@app.route('/xxx')
def xxx():
resp = make_response('响应内容')
# 允许实现其他的响应行为
return resp
3.重定向
1.什么是重定向
由服务器端通知客户端重新向一个新的地址发送请求
2.语法
from flask import redirect
@app.route("/zengsf")
# 比如首页地址为"/",那就redirect("/")
return redirect('重定向地址')
from flask import Flask,render_template,redirect,send_file,jsonify,request app = Flask(__name__) @app.route("/") def index(): return "hello S17" @app.route("/login") def login(): return render_template("login.html") @app.route("/image") def image(): return redirect("/get_file") @app.route("/get_file") def get_file(): return send_file("1.mp4") import json @app.route("/get_json") def get_json(): dict = {"name":"value"} # dict_json = json.dumps(dict) return jsonify(dict) app.run(debug=True)
典型示例
@change.route('/change/<int:num>',methods=['POST','GET']) def change_func(num): student=STUDENT_DICT[num] if request.method=='POST': stuname=request.form.get('stuname') age=request.form.get('age') sex=request.form.get('sex') STUDENT_DICT[num]={'name': stuname, 'age': int(age), 'gender': sex} return redirect('/check') return render_template('student_ch.html',stu=student)
@gsa.route("/get_cover/<filename>") def get_cover(filename): cover_file = os.path.join(COVER_PATH,filename) return send_file(cover_file)
@devices.route("/scan_qr",methods=["POST"]) def scan_qr(): device_key = request.form.to_dict() # {"device_key":341252346} res = MONGODB.devices.find_one(device_key) if res:# 1.扫码的二维码存在于数据库中 Devices 数据表中 RET["CODE"] = 0 RET["MSG"] = "扫描二维码成功" RET["DATA"] = device_key else: # 2.扫描的二维码不在数据库中 RET["CODE"] = 1 RET["MSG"] = "滚犊子" RET["DATA"] = {} return jsonify(RET)
方式一:flask自带session使用,必须记得添加secret_key才能生效
from flask import session, Flask
app01.config["SECRET_KEY"] = "@#$%^&*"
app.secret_key = os.urandom(24)
app = Flask(__name__)
@app.route("/login")
def login():
session["key"] = "value"
return "已经创建了session"
@app.route("/look")
def look():
return session.get("key")
# 删除session
@app.route("/delSession/")
def delSession():
session.pop('sessioninfo', None)
return "session删除成功"
方式二:使用flask_session模块配置
flask-session是flask框架的session组件,由于原来flask内置session使用签名cookie保存,该组件则将支持session保存到多个地方
import redis from flask import Flask, session from flask_session import Session app = Flask(__name__) app.debug = True app.secret_key = 'xxxx' app.config['SESSION_TYPE'] = 'redis' # session类型为redis app.config['SESSION_PERMANENT'] = False # 如果设置为True,则关闭浏览器session就失效。 app.config['SESSION_USE_SIGNER'] = False # 是否对发送到浏览器上session的cookie值进行加密 app.config['SESSION_KEY_PREFIX'] = 'session:' # 保存到session中的值的前缀 app.config['SESSION_REDIS'] = redis.Redis(host='127.0.0.1', port='6379', password='123123') # 用于连接redis的配置 Session(app) @app.route('/index') def index(): session['k1'] = 'v1' return 'xx' if __name__ == '__main__': app.run()
1.路由装饰器
@getanything.route('/get_cover/<filename>', methods=['POST', 'GET'], strict_slashes=False) def getcover_func(filename): cover_path = os.path.join(COVER_PATH, filename) return send_file(cover_path)
@login.route('/login',methods=['GET','POST'],endpoint='login',strict_slashes=False)
2.类中间件装饰器
装饰器及其执行顺序:errorhandler-->before_request-->after_request
无参装饰器加在路由装饰器后边,加在路由装饰器之前不起作用
@app.before_request#请求进入视图函数之前,在其中验证session情况
@app.before_request用法:
@app.before_request def confirm(): """ 在执行视图函数之前执行 :return: """ if session.get('auth') or request.path == "/login" or request.path.startswith('/static'): return None else: next_url = request.path return redirect('/login?next=%s' % (next_url,))
@index.before_request def mysession(): if session.get('user'): return None else: return redirect('/login')
@app.after_request用法:
@app.after_request def access_login(response): """ 视图函数执行完毕并执行成功后执行 :param response: 必须接受一个response :return: """ ip = request.remote_addr url = request.path print("%s访问 %s 成功" % (ip, url)) return response # 必须返回一个response对象
@app.after_request def af3(resp): print("af3") return resp
@app.errorhandler(404)
@app.errorhandler(404) # 404: 监听的错误码 def error(args): """ 当出现某个错误状态码时会调用这个函数 :param args: 错误信息 :return: """ return render_template("error.html")
@app.errorhandler(404) def errors(status): return send_file('404错误.jpg')
3.类装饰器
from flask import Flask,request,views from functools import wraps app = Flask(__name__) #自定义登录装饰器 def login_required(func): @wraps(func) def wapper(*args,**kwargs): username = request.args.get('username') if username and username == 'xiaowu': return func(*args,**kwargs) else: return '请先登录' return wapper @app.route('/') def index(): return '网站首页' @app.route('/setting/') @login_required def setting(): return '这是设置页面' #类视图怎么使用装饰器 class ProfileView(views.View): decorators = [login_required] def dispatch_request(self): return "个人中心页面" app.add_url_rule('/profile/',endpoint='profile',view_func=ProfileView.as_view( 'profile' )) if __name__ == '__main__': app.run(debug=True)
from flask import Flask, views from flask_session import Session app=Flask(__name__) Session(app) app.secret_key='ankjfbab' class Login(views.MethodView): def get(self): return 'return 方法' app.add_url_rule('/login',endpoint=None,view_func=Login.as_view(name='login')) if __name__== "__main__": app.run("127.0.0.1",5001)