Flask使用的是Jinja2模板,所以其语法和Django无差别
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%}
当请求刚到来时: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"
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)
# -*- 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
# -*- 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'