Flask详解(中)

tech2024-05-08  85

一 Flask请求和响应

from flask import Flask from flask import request from flask import render_template from flask import redirect from flask import make_response app = Flask(__name__) @app.route('/login.html', methods=['GET', "POST"]) def login():

 

请求相关信息

# request.method # request.args 获取GET方式的url参数 # request.form form提交的数据取值 # request.values 同时获得form和args的值 # request.json 请求头是contenttype:application/json 将字典序列化成jason # request.data contenttype请求无法解析时会以byte放入data # request.cookies # request.headers # request.path # request.full_path # request.script_root # request.url # request.base_url # request.url_root # request.host_url # request.host # request.files # obj = request.files['the_file_name'] # obj.save('/var/www/uploads/' + secure_filename(f.filename))

 

响应相关信息

# return "字符串" # return render_template('html模板路径',**{}) # return redirect('/index.html') # response = make_response(render_template('index.html')) # response是flask.wrappers.Response类型 # response.delete_cookie('key') # response.set_cookie('key', 'value') # response.headers['X-Something'] = 'A value' # return response # return jsonfiy 返回序列化的json数据 # return send_file(file_name) 返回一个文件

 

二 模板语言

1、模板的使用

Flask使用的是Jinja2模板,所以其语法和Django无差别

2、自定义模板方法

Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,如:

 

from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response,Markup from urllib.parse import urlencode,quote,unquote app = Flask(__name__) def test(a1,a2): return a1+a2 @app.template_global() def sb(a1,a2): return a1 + a2 + 100 @app.template_filter() def db(a1, a2, a3): return a1 + a2 + a3 @app.route('/index',endpoint='xx') def index(): v1 = "字符串" v2 = [11,22,33] v3 = {'k1':'v1','k2':'v2'} v4 = Markup("<input type='text' />") return render_template('index.html',v1=v1,v2=v2,v3=v3,v4=v4,test=test) ''' 函数模板 ''' from common.libs.UrlManager import UrlManager app.add_template_global(UrlManager.buildStaticUrl, 'buildStaticUrl') app.add_template_global(UrlManager.buildUrl, 'buildUrl') app.add_template_global(UrlManager.buildImageUrl, 'buildImageUrl') if __name__ == '__main__': # app.__call__ app.run()

 

layout.html:

 

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>模板</h1> {%block body %} {%endblock%} </body> </html>

 

index.html

 

{% extends 'layout.html'%} {%block body %} {{v1}} <ul> {% for item in v2 %} <li>{{item}}</li> {% endfor %} </ul> {{v2.1}} <ul> {% for k,v in v3.items() %} <li>{{k}} {{v}}</li> {% endfor %} </ul> {{v3.k1}} {{v3.get('k1')}} {{v4}} <!--{{v4|safe}}--> <h1>{{test(1,19)}}</h1> {{sb(1,2)}} {{ 1|db(2,3)}} {% macro xxxx(name, type='text', value='') %} <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> <input type="{{ type }}" name="{{ name }}" value="{{ value }}"> {% endmacro %} {{ xxxx('n1') }} {%endblock%}

 

三 session

当请求刚到来时:Flask会读取cookie中session对应的值。 将这个值解密并反序列化成字典放入内存以便视图函数使用

视图函数:

 

@app.route('/ses') def ses(): session['k1'] = 123 session['k2'] = 456 del session['k1'] return session

 

# 注意要在使用之前设置secret key 

app.secret_key = 'sdfsdfsdf'

当请求结束时,Flask会读取内存中字典的值,进行序列化+加密,再写入到用户的cookie中

四 闪现

闪现是指在session中存储一个数据,读取时通过pop将数据移除

 

from flask import Flask,flash,get_flashed_messages @app.route('/page1') def page1(): flash('临时数据存储', 'error') flash('sdfsdfsdffsdf', 'error') flash('asdfsdfsdfdsf', 'info') return "Session" @app.route('/page2') def page2(): print(get_flashed_messages(category_filter=['error'])) return "Session"

 

 五 中间件

在call方法执行之前加入其它功能,实现类似中间件的功能

 

from flask import Flask, flash, redirect, render_template, request app = Flask(__name__) app.secret_key = 'some_secret' @app.route('/') def index1(): return render_template('index.html') @app.route('/set') def index2(): v = request.args.get('p') flash(v) return 'ok' class MiddleWare: def __init__(self,wsgi_app): self.wsgi_app = wsgi_app def __call__(self, *args, **kwargs): # 在call方法执行之前加入其它功能,实现类似中间件的功能 return self.wsgi_app(*args, **kwargs) if __name__ == "__main__": app.wsgi_app = MiddleWare(app.wsgi_app) app.run(port=9999)

 

六 特殊装饰器

- before_firset_request- before_request # 再请求进入视图函数之前做出处理- after_request # 再请求结束视图函数之后,返回客户端之前 def go(response) return response 逆向执行    # 正常场景be1-be2-af2-af1 异常场景 be1-af2-af1- template_global()- template_filter()- errorhandler (404) # 在使用errorheadler传递参数 404 500 error(code_or_exp) return redirect("/index")

 拦截验证用户是否登录的方法:

 

# -*- coding: utf-8 -*- from application import app from flask import request,g,redirect from common.models.User import ( User ) from common.libs.user.UserService import ( UserService ) from common.libs.UrlManager import ( UrlManager ) from common.libs.LogService import LogService import re @app.before_request def before_request(): ignore_urls = app.config['IGNORE_URLS'] ignore_check_login_urls = app.config['IGNORE_CHECK_LOGIN_URLS'] path = request.path # 如果是静态文件就不要查询用户信息了 pattern = re.compile('%s' % "|".join(ignore_check_login_urls)) if pattern.match(path): return if '/api' in path: return user_info = check_login() g.current_user = None if user_info: g.current_user = user_info # #加入日志 # LogService.addAccessLog() pattern = re.compile('%s' % "|".join(ignore_urls)) if pattern.match(path): return if not user_info : return redirect( UrlManager.buildUrl( "/user/login" ) ) return ''' 判断用户是否已经登录 ''' def check_login(): cookies = request.cookies auth_cookie = cookies[app.config['AUTH_COOKIE_NAME']] if app.config['AUTH_COOKIE_NAME'] in cookies else None if '/api' in request.path: app.logger.info(request.path) auth_cookie = request.headers.get("Authorization") app.logger.info( request.headers.get("Authorization") ) if auth_cookie is None: return False auth_info = auth_cookie.split("#") if len(auth_info) != 2: return False try: user_info = User.query.filter_by(uid=auth_info[1]).first() except Exception: return False if user_info is None: return False if auth_info[0] != UserService.geneAuthCode( user_info ): return False if user_info.status != 1: return False return user_info

 

404错误拦截

 

# -*- coding: utf-8 -*- from application import app from common.libs.Helper import ops_render from common.libs.LogService import LogService @app.errorhandler(404) def error_404(e): LogService.addErrorLog(str(e)) return ops_render('error/error.html', {'status': 404, 'msg': '很抱歉!您访问的页面不存在'})

 

七 蓝图

简单来说,Blueprint 是一个存储操作方法的容器,这些操作在这个Blueprint 被注册到一个应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。

Flask使用Blueprint让应用实现模块化,在Flask中,Blueprint具有如下属性:

一个应用可以具有多个Blueprint可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名在一个应用中,一个模块可以注册多次Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的在一个应用初始化时,就应该要注册需要使用的Blueprint

但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。

使用蓝图的实例:

  

结构: Mycrm   crm     static     template       login.html     views       account.py       order.py     models.py     __init__.py   manage.py   settings.py

  

__init__.py:

 

from flask import Flask from .views import account from .views import order app = Flask(__name__) print(app.root_path) # 注意一定要注册注册蓝图 app.register_blueprint(account.account) app.register_blueprint(order.order)

 

manage.py:

import crm if __name__ == '__main__' mycrm.app.runn()

account.py:

 

from flask import Blueprint,render_template account = Blueprint('account',__name__,) @account.route('/login') def login(): # return 'Login' return render_template('login.html')

 

order.py:

 

from flask import Blueprint order = Blueprint('order',__name__) @order.route('/order') def login(): return 'Order'
最新回复(0)