Flask【第2篇】:Flask基础
Flask基础
知识点回顾
1、flask依赖wsgi,实现wsgi的模块:wsgiref,werkzeug,uwsgi
2、实例化Flask对象,里面是有参数的
- app = Flask(__name__,template_folder='templates',static_url_path='/xxxxxx')
3、两种添加路由的方式

- 方式一:
- @app.route('/xxxx') # @decorator
- def index():
- return "Index"
- 方式二:
- def index():
- return "Index"
- app.add_url_rule('/xxx', "n1", index) #n1是别名

4、添加路由关系的本质
将url和视图函数封装成一个Rule对象)添加到Flask的url_map字段中
5、Flask中装饰器应用

- from flask import Flask,render_template,request,redirect,session
- app = Flask(__name__)
- app.secret_key = "sdsfdsgdfgdfgfh"
- def wrapper(func):
- def inner(*args,**kwargs):
- if not session.get("user_info"):
- return redirect("/login")
- ret = func(*args,**kwargs)
- return ret
- return inner
- @app.route("/login",methods=["GET","POST"])
- def login():
- if request.method=="GET":
- return render_template("login.html")
- else:
- # print(request.values) #这个里面什么都有,相当于body
- username = request.form.get("username")
- password = request.form.get("password")
- if username=="haiyan" and password=="123":
- session["user_info"] = username
- # session.pop("user_info") #删除session
- return redirect("/index")
- else:
- # return render_template("login.html",**{"msg":"用户名或密码错误"})
- return render_template("login.html",msg="用户名或者密码错误")
- @app.route("/index",methods=["GET","POST"])
- @wrapper
- def index():
- # if not session.get("user_info"):
- # return redirect("/login")
- return render_template("index.html")
- if __name__ == '__main__':
- app.run(debug=True)

5、请求响应相关

- - request
- - request.form #POST请求
- - request.args #GET请求 字典形式的
- - request.querystring #GET请求,bytes形式的
- - response
- - return render_tempalte()
- - return redirect()
- - return ""
- v = make_response(返回值) #吧返回的值包在了这个函数里面
- - session
- - 存在浏览器上,并且是加密的
- - 依赖于:secret_key

flask配置文件
- 1 flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:
- 2 {
- 3 'DEBUG': get_debug_flag(default=False), 是否开启Debug模式
- 4 'TESTING': False, 是否开启测试模式
- 5 'PROPAGATE_EXCEPTIONS': None,
- 6 'PRESERVE_CONTEXT_ON_EXCEPTION': None,
- 7 'SECRET_KEY': None,
- 8 'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
- 9 'USE_X_SENDFILE': False,
- 10 'LOGGER_NAME': None,
- 11 'LOGGER_HANDLER_POLICY': 'always',
- 12 'SERVER_NAME': None,
- 13 'APPLICATION_ROOT': None,
- 14 'SESSION_COOKIE_NAME': 'session',
- 15 'SESSION_COOKIE_DOMAIN': None,
- 16 'SESSION_COOKIE_PATH': None,
- 17 'SESSION_COOKIE_HTTPONLY': True,
- 18 'SESSION_COOKIE_SECURE': False,
- 19 'SESSION_REFRESH_EACH_REQUEST': True,
- 20 'MAX_CONTENT_LENGTH': None,
- 21 'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
- 22 'TRAP_BAD_REQUEST_ERRORS': False,
- 23 'TRAP_HTTP_EXCEPTIONS': False,
- 24 'EXPLAIN_TEMPLATE_LOADING': False,
- 25 'PREFERRED_URL_SCHEME': 'http',
- 26 'JSON_AS_ASCII': True,
- 27 'JSON_SORT_KEYS': True,
- 28 'JSONIFY_PRETTYPRINT_REGULAR': True,
- 29 'JSONIFY_MIMETYPE': 'application/json',
- 30 'TEMPLATES_AUTO_RELOAD': None,
- 31 }
- 32
- 33 方式一:
- 34 app.config['DEBUG'] = True
- 35
- 36 PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...)
- 37
- 38 方式二:
- 39 app.config.from_pyfile("python文件名称")
- 40 如:
- 41 settings.py
- 42 DEBUG = True
- 43
- 44 app.config.from_pyfile("settings.py")
- 45
- 46 app.config.from_envvar("环境变量名称")
- 47 环境变量的值为python文件名称名称,内部调用from_pyfile方法
- 48
- 49
- 50 app.config.from_json("json文件名称")
- 51 JSON文件名称,必须是json格式,因为内部会执行json.loads
- 52
- 53 app.config.from_mapping({'DEBUG':True})
- 54 字典格式
- 55
- 56 app.config.from_object("python类或类的路径")
- 57
- 58 app.config.from_object('pro_flask.settings.TestingConfig')
- 59
- 60 settings.py
- 61
- 62 class Config(object):
- 63 DEBUG = False
- 64 TESTING = False
- 65 DATABASE_URI = 'sqlite://:memory:'
- 66
- 67 class ProductionConfig(Config):
- 68 DATABASE_URI = 'mysql://user@localhost/foo'
- 69
- 70 class DevelopmentConfig(Config):
- 71 DEBUG = True
- 72
- 73 class TestingConfig(Config):
- 74 TESTING = True
- 75
- 76 PS: 从sys.path中已经存在路径开始写
- 77
- 78
- 79 PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录
配置文件
一、路由系统
1、可传入参数:
- @app.route('/user/<username>') #常用的 不加参数的时候默认是字符串形式的
- @app.route('/post/<int:post_id>') #常用的 #指定int,说明是整型的
- @app.route('/post/<float:post_id>')
- @app.route('/post/<path:path>')
- @app.route('/login', methods=['GET', 'POST'])
常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:

- DEFAULT_CONVERTERS = {
- 'default': UnicodeConverter,
- 'string': UnicodeConverter,
- 'any': AnyConverter,
- 'path': PathConverter,
- 'int': IntegerConverter,
- 'float': FloatConverter,
- 'uuid': UUIDConverter,
- }

2、反向生成URL: url_for
endpoint("name") #别名,相当于django中的name
反向解析需要导入:
- from flask import Flask, url_for

- @app.route('/index',endpoint="xxx") #endpoint是别名
- def index():
- v = url_for("xxx")
- print(v)
- return "index"
- @app.route('/zzz/<int:nid>',endpoint="aaa") #endpoint是别名
- def zzz(nid):
- v = url_for("aaa",nid=nid)
- print(v)
- return "index2"

3、@app.route和app.add_url_rule参数

- @app.route和app.add_url_rule参数:
- rule, URL规则
- view_func, 视图函数名称
- defaults=None, 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
- endpoint=None, 名称,用于反向生成URL,即: url_for('名称')
- methods=None, 允许的请求方式,如:["GET","POST"]
- strict_slashes=None, 对URL最后的 / 符号是否严格要求,
- 如:
- @app.route('/index',strict_slashes=False),
- 访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
- @app.route('/index',strict_slashes=True)
- 仅访问 http://www.xx.com/index
- redirect_to=None, 重定向到指定地址
- 如:
- @app.route('/index/<int:nid>', redirect_to='/home/<nid>')
- 或
- def func(adapter, nid):
- return "/home/888"
- @app.route('/index/<int:nid>', redirect_to=func)
- subdomain=None, 子域名访问
- from flask import Flask, views, url_for
- app = Flask(import_name=__name__)
- app.config['SERVER_NAME'] = 'haiyan.com:5000'
- @app.route("/", subdomain="admin")
- def static_index():
- """Flask supports static subdomains
- This is available at static.your-domain.tld"""
- return "admin.xxx.com"
- #动态生成
- @app.route("/dynamic", subdomain="<username>")
- def username_index(username):
- """Dynamic subdomains are also supported
- Try going to user1.your-domain.tld/dynamic"""
- return username + ".your-domain.tld"
- if __name__ == '__main__':
- app.run()
- 所有的域名都得与IP做一个域名解析:
如果你想通过域名去访问,有两种解决方式:
方式一:
1、租一个域名 haiyan.lalala
2、租一个公网IP 49.8.5.62
3、域名解析:
haiyan.com 49.8.5.62
- 4、吧代码放在49.8.5.62这个服务器上,程序运行起来
用户可以通过IP进行访问
- 方式二:如果是自己测试用的就可以用这种方式。先在自己本地的文件中找
C:\Windows\System32\drivers\etc 找到HOST,修改配置
然后吧域名修改成自己的本地服务器127.0.0.1
加上配置:app.config["SERVER_NAME"] = "haiyan.com:5000"

练习以上的参数
- redirect_to:直接重定向,原url有参数时,跳转是也得传参,注意:不用加类型

- #/old
- @app.route('/old/<int:nid>',redirect_to="/new/<nid>")
- def old(nid):
- return "old"
- # /new
- @app.route('/new/<int:nid>')
- def new(nid):
- return "new"


- # ============对url最后的/符号是否严格要求=========
- @app.route('/test',strict_slashes=True) #当为True时,url后面必须不加斜杠
- def test():
- return "aaaaaaaa"
- @app.route('/test',strict_slashes=False) #当为False时,url上加不加斜杠都行
- def test():
- return "aaaaaaaa"


- # =============== 子域名访问============
- @app.route("/static_index", subdomain="admin")
- def static_index():
- return "admin.bjg.com"
- # ===========动态生成子域名===========
- @app.route("/index",subdomain='<xxxxx>')
- def index(xxxxx):
- return "%s.bjg.com" %(xxxxx,)

扩展Flask的路由系统,让他支持正则,这个类必须这样写,必须去继承BaseConverter

- from flask import Flask,url_for
- app = Flask(__name__)
- # 定义转换的类
- from werkzeug.routing import BaseConverter
- class RegexConverter(BaseConverter):
- """
- 自定义URL匹配正则表达式
- """
- def __init__(self, map, regex):
- super(RegexConverter, self).__init__(map)
- self.regex = regex
- def to_python(self, value):
- """
- 路由匹配时,匹配成功后传递给视图函数中参数的值
- :param value:
- :return:
- """
- return int(value)
- def to_url(self, value):
- """
- 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
- :param value:
- :return:
- """
- val = super(RegexConverter, self).to_url(value)
- return val
- # 添加到converts中
- app.url_map.converters['regex'] = RegexConverter
- # 进行使用
- @app.route('/index/<regex("\d+"):nid>',endpoint='xx')
- def index(nid):
- url_for('xx',nid=123) #反向生成,就会去执行to_url方法
- return "Index"
- if __name__ == '__main__':
- app.run()

二、视图函数
1、diango中的CBV模式
2、Flask中的CBV模式

- def auth(func):
- def inner(*args, **kwargs):
- result = func(*args, **kwargs)
- return result
- return inner
- class IndexView(views.MethodView):
- # methods = ['POST'] #只允许POST请求访问
- decorators = [auth,] #如果想给所有的get,post请求加装饰器,就可以这样来写,也可以单个指定
- def get(self): #如果是get请求需要执行的代码
- v = url_for('index')
- print(v)
- return "GET"
- def post(self): #如果是post请求执行的代码
- return "POST"
- app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) #name指定的是别名,会当做endpoint使用
- if __name__ == '__main__':
- app.run()

3、Flask中的FBV模式
两种方式:

- 方式一:
- @app.route('/index',endpoint='xx')
- def index(nid):
- url_for('xx',nid=123)
- return "Index"
- 方式二:
- def index(nid):
- url_for('xx',nid=123)
- return "Index"
- app.add_url_rule('/index',index)

三、请求与响应
- 1 from flask import Flask
- 2 from flask import request
- 3 from flask import render_template
- 4 from flask import redirect
- 5 from flask import make_response
- 6
- 7 app = Flask(__name__)
- 8
- 9
- 10 @app.route('/login.html', methods=['GET', "POST"])
- 11 def login():
- 12
- 13 # 请求相关信息
- 14 # request.method
- 15 # request.args
- 16 # request.form
- 17 # request.values
- 18 # request.cookies
- 19 # request.headers
- 20 # request.path
- 21 # request.full_path
- 22 # request.script_root
- 23 # request.url
- 24 # request.base_url
- 25 # request.url_root
- 26 # request.host_url
- 27 # request.host
- 28 # request.files
- 29 # obj = request.files['the_file_name']
- 30 # obj.save('/var/www/uploads/' + secure_filename(f.filename))
- 31
- 32 # 响应相关信息
- 33 # return "字符串"
- 34 # return render_template('html模板路径',**{})
- 35 # return redirect('/index.html')
- 36
- 37 # response = make_response(render_template('index.html'))
- 38 # response是flask.wrappers.Response类型
- 39 # response.delete_cookie('key')
- 40 # response.set_cookie('key', 'value')
- 41 # response.headers['X-Something'] = 'A value'
- 42 # return response
- 43
- 44
- 45 return "内容"
- 46
- 47 if __name__ == '__main__':
- 48 app.run()

- from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
- from urllib.parse import urlencode,quote,unquote
- app = Flask(__name__)
- @app.route('/index',endpoint='xx')
- def index():
- from werkzeug.datastructures import ImmutableMultiDict
=================- # get_data = request.args
- # get_dict = get_data.to_dict()
- # get_dict['xx'] = '18'
- # url = urlencode(get_dict)
- # print(url)
- ====================
- # print(request.query_string)
- # print(request.args)
- ==========================
- # val = "%E6%8A%8A%E5%87%A0%E4%B8%AA"
- # print(unquote(val)) #吧上面这样的数据转换成中文
- #
- # return "Index"
- # return "Index"
- # return redirect()
- # return render_template()
- # return jsonify(name='alex',age='18') #相当于JsonResponse
- =======================
- response = make_response('xxxxx') ##如果是返回更多的值,cookie,headers,或者其他的就可用它
- response.headers['xxx'] = '123123'
- return response
- if __name__ == '__main__':
- # app.__call__
- app.run()

四、模板语法
1、为了防止xss攻击,加了验证,所以页面上显示字符串的形式,解决办法,有两种方式
- 在后端Markup
- v5 = Markup("<input type='text' />")
- 在前端
- {{ v4|safe }}
2、自定义方法

- def test(a,b):
- return a+b
- @app.route('/index')
- def index():
- return render_template("index2.html",test=test)
- index2.html
- <h1>{{ test(1,2) }}</h1>

3、写一个函数在所有的页面都使用
template_global和template_filter

- @app.template_global()
- def sb(a1, a2):
- return a1 + a2
- @app.template_filter()
- def db(a1, a2, a3):
- return a1 + a2 + a3

- 调用方式:{{sb(1,2)}} {{ 1|db(2,3)}}
4、模板继承:和django的一样。extents
5、宏:只有定义的东西在很多地方去使用的时候才去用它
- {% macro input(name, type='text', value='') %}
- <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
- {% endmacro %}
- {{ input('n1') }}
练习:
- 1 from flask import Flask,url_for,render_template,Markup
- 2 app = Flask(__name__)
- 3
- 4 def test(a,b):
- 5 return a+b
- 6
- 7 @app.template_global()
- 8 def sb(a1, a2):
- 9 return a1 + a2 + 100
- 10
- 11
- 12 @app.template_filter()
- 13 def db(a1, a2, a3):
- 14 return a1 + a2 + a3
- 15
- 16 @app.route('/index')
- 17 def index():
- 18 v1 = "字符串"
- 19 v2 = [11,22,33]
- 20 v3 = {"k1":"v3","sdf":"sdgfgf"}
- 21 v4 = "<input type='text' />"
- 22 v5 = Markup("<input type='text' />")
- 23 return render_template("index2.html",v1=v1,v2=v2,v3=v3,v4=v4,v5=v5,test=test)
- 24
- 25 if __name__ == '__main__':
- 26 app.run(debug=True)
模板语法
- 1 <!DOCTYPE html>
- 2 <html lang="en">
- 3 <head>
- 4 <meta charset="UTF-8">
- 5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
- 6 <meta name="viewport" content="width=device-width">
- 7 <title>Title</title>
- 8 </head>
- 9 <body>
- 10 {{ v1 }}
- 11 <ul>
- 12 {% for foo in v2 %}
- 13 <li>{{ foo }}</li>
- 14 {% endfor %}
- 15 {{ v2.1 }}
- 16
- 17 {% for k,v in v3.items() %}
- 18 <li>{{ k }} {{ v }}</li>
- 19 {% endfor %}
- 20 {{ v3.k1 }}
- 21 {{ v3.get("k1") }}
- 22
- 23 {{ v4|safe }}
- 24 {{ v5 }}
- 25
- 26 <h1>{{ test(1,2) }}</h1>
- 27 <p>{{ sb(1,2) }}</p>
- 28 <p>{{ 1| db(2,3) }}</p>
- 29 </ul>
- 30 </body>
- 31 </html>
index2.html
五、session
除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。
设置:session['username'] = 'xxx'
- 删除:session.pop('username', None)

- from flask import Flask,url_for,session
- app = Flask(__name__)
- app.secret_key = "sdsfdgdgdgd"
- app.config['SESSION_COOKIE_NAME'] = 'session_lvning' #设置session的名字
- @app.route('/index/')
- def index(nid):
- #session本质上操作的是字典, session是否还有其他方法?与字典方法相同
- #session的原理:如果下一次访问的时候带着随机字符串,会把session里面对应的
- # 值拿到内存,假设session保存在数据库,每执行一次链接一次数据库,每次都要时时更新的话
- # 会非常损耗内存
- session["xxx"] = 123
- session["xxx2"] = 123
- session["xxx3"] = 123
- session["xxx4"] = 123
- del session["xxx2"] #在这删除了,真正存储的时候是没有xxx2的
- return "ddsf"
- if __name__ == '__main__':
- app.run()

关于session的配置
- app.config['SESSION_COOKIE_NAME'] = 'session_lvning'

- - session超时时间如何设置? 'PERMANENT_SESSION_LIFETIME': timedelta(days=31)
- 以下是跟session相关的配置文件
- """
- 'SESSION_COOKIE_NAME': 'session',
- 'SESSION_COOKIE_DOMAIN': None,
- 'SESSION_COOKIE_PATH': None,
- 'SESSION_COOKIE_HTTPONLY': True,
- 'SESSION_COOKIE_SECURE': False,
- 'SESSION_REFRESH_EACH_REQUEST': True, #是否每次都跟新
- 'PERMANENT_SESSION_LIFETIME': timedelta(days=31)

- 1 from flask import Flask, session, redirect, url_for, escape, request
- 2
- 3 app = Flask(__name__)
- 4
- 5 @app.route('/')
- 6 def index():
- 7 if 'username' in session:
- 8 return 'Logged in as %s' % escape(session['username'])
- 9 return 'You are not logged in'
- 10
- 11 @app.route('/login', methods=['GET', 'POST'])
- 12 def login():
- 13 if request.method == 'POST':
- 14 session['username'] = request.form['username']
- 15 return redirect(url_for('index'))
- 16 return '''
- 17 <form action="" method="post">
- 18 <p><input type=text name=username>
- 19 <p><input type=submit value=Login>
- 20 </form>
- 21 '''
- 22
- 23 @app.route('/logout')
- 24 def logout():
- 25 # remove the username from the session if it's there
- 26 session.pop('username', None)
- 27 return redirect(url_for('index'))
- 28
- 29 # set the secret key. keep this really secret:
- 30 app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
基本使用
- 1 pip3 install Flask-Session
- 2
- 3 run.py
- 4 from flask import Flask
- 5 from flask import session
- 6 from pro_flask.utils.session import MySessionInterface
- 7 app = Flask(__name__)
- 8
- 9 app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
- 10 app.session_interface = MySessionInterface()
- 11
- 12 @app.route('/login.html', methods=['GET', "POST"])
- 13 def login():
- 14 print(session)
- 15 session['user1'] = 'alex'
- 16 session['user2'] = 'alex'
- 17 del session['user2']
- 18
- 19 return "内容"
- 20
- 21 if __name__ == '__main__':
- 22 app.run()
- 23
- 24 session.py
- 25 #!/usr/bin/env python
- 26 # -*- coding:utf-8 -*-
- 27 import uuid
- 28 import json
- 29 from flask.sessions import SessionInterface
- 30 from flask.sessions import SessionMixin
- 31 from itsdangerous import Signer, BadSignature, want_bytes
- 32
- 33
- 34 class MySession(dict, SessionMixin):
- 35 def __init__(self, initial=None, sid=None):
- 36 self.sid = sid
- 37 self.initial = initial
- 38 super(MySession, self).__init__(initial or ())
- 39
- 40
- 41 def __setitem__(self, key, value):
- 42 super(MySession, self).__setitem__(key, value)
- 43
- 44 def __getitem__(self, item):
- 45 return super(MySession, self).__getitem__(item)
- 46
- 47 def __delitem__(self, key):
- 48 super(MySession, self).__delitem__(key)
- 49
- 50
- 51
- 52 class MySessionInterface(SessionInterface):
- 53 session_class = MySession
- 54 container = {}
- 55
- 56 def __init__(self):
- 57 import redis
- 58 self.redis = redis.Redis()
- 59
- 60 def _generate_sid(self):
- 61 return str(uuid.uuid4())
- 62
- 63 def _get_signer(self, app):
- 64 if not app.secret_key:
- 65 return None
- 66 return Signer(app.secret_key, salt='flask-session',
- 67 key_derivation='hmac')
- 68
- 69 def open_session(self, app, request):
- 70 """
- 71 程序刚启动时执行,需要返回一个session对象
- 72 """
- 73 sid = request.cookies.get(app.session_cookie_name)
- 74 if not sid:
- 75 sid = self._generate_sid()
- 76 return self.session_class(sid=sid)
- 77
- 78 signer = self._get_signer(app)
- 79 try:
- 80 sid_as_bytes = signer.unsign(sid)
- 81 sid = sid_as_bytes.decode()
- 82 except BadSignature:
- 83 sid = self._generate_sid()
- 84 return self.session_class(sid=sid)
- 85
- 86 # session保存在redis中
- 87 # val = self.redis.get(sid)
- 88 # session保存在内存中
- 89 val = self.container.get(sid)
- 90
- 91 if val is not None:
- 92 try:
- 93 data = json.loads(val)
- 94 return self.session_class(data, sid=sid)
- 95 except:
- 96 return self.session_class(sid=sid)
- 97 return self.session_class(sid=sid)
- 98
- 99 def save_session(self, app, session, response):
- 100 """
- 101 程序结束前执行,可以保存session中所有的值
- 102 如:
- 103 保存到resit
- 104 写入到用户cookie
- 105 """
- 106 domain = self.get_cookie_domain(app)
- 107 path = self.get_cookie_path(app)
- 108 httponly = self.get_cookie_httponly(app)
- 109 secure = self.get_cookie_secure(app)
- 110 expires = self.get_expiration_time(app, session)
- 111
- 112 val = json.dumps(dict(session))
- 113
- 114 # session保存在redis中
- 115 # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
- 116 # session保存在内存中
- 117 self.container.setdefault(session.sid, val)
- 118
- 119 session_id = self._get_signer(app).sign(want_bytes(session.sid))
- 120
- 121 response.set_cookie(app.session_cookie_name, session_id,
- 122 expires=expires, httponly=httponly,
- 123 domain=domain, path=path, secure=secure)
自定义Session
- 1 #!/usr/bin/env python
- 2 # -*- coding:utf-8 -*-
- 3 """
- 4 pip3 install redis
- 5 pip3 install flask-session
- 6
- 7 """
- 8
- 9
- 10 from flask import Flask, session, redirect
- 11 from flask.ext.session import Session
- 12
- 13
- 14 app = Flask(__name__)
- 15 app.debug = True
- 16 app.secret_key = 'asdfasdfasd'
- 17
- 18
- 19 app.config['SESSION_TYPE'] = 'redis'
- 20 from redis import Redis
- 21 app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='')
- 22 Session(app)
- 23
- 24
- 25 @app.route('/login')
- 26 def login():
- 27 session['username'] = 'alex'
- 28 return redirect('/index')
- 29
- 30
- 31 @app.route('/index')
- 32 def index():
- 33 name = session['username']
- 34 return name
- 35
- 36
- 37 if __name__ == '__main__':
- 38 app.run()
第三方session
六、blueprint,蓝图
七、闪现 : flash
session存在在服务端的一个字典里面,session保存起来,取一次里面还是有的,直到你删除之后才没有了
1、本质:flash是基于session创建的,flash支持往里边放值,只要你取一下就没有了,相当于pop了一下。不仅吧值取走,而且吧session里的东西去掉
2、闪现有什么用?

- from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
- app = Flask(__name__)
- app.secret_key ='sdfsdfsdf'
- @app.route('/users')
- def users():
- # 方式一
- # msg = request.args.get('msg','')
- # 方式二
- # msg = session.get('msg')
- # if msg:
- # del session['msg']
- # 方式三
- v = get_flashed_messages()
- print(v)
- msg = ''
- return render_template('users.html',msg=msg)
- @app.route('/useradd')
- def user_add():
- # 在数据库中添加一条数据
- # 假设添加成功,在跳转到列表页面时,显示添加成功
- # 方式一
- # return redirect('/users?msg=添加成功')
- # 方式二
- # session['msg'] = '添加成功'
- # 方式三
- flash('添加成功')
- return redirect('/users')
- if __name__ == '__main__':
- app.run(debug=True)

八、扩展
1、在函数执行之前或函数执行之后做点事情
第一种:装饰器
第二种:flask里面的扩展,相当于django中的中间件

- from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
- app = Flask(__name__)
- app.secret_key ='sdfsdfsdf'
- @app.before_request
- def process_request1():
- print('process_request1')
- @app.after_request
- def process_response1(response):
- print('process_response1')
- return response
- @app.before_request
- def process_request2():
- print('process_request2')
- @app.after_request
- def process_response2(response): #参数也得有
- print('process_response2')
- return response #必须有返回值
- @app.route('/index')
- def index():
- print('index')
- return 'Index'
- @app.route('/order')
- def order():
- print('order')
- return 'order'
- @app.route('/test')
- def test():
- print('test')
- return 'test'
- if __name__ == '__main__':
- app.run()

运行结果:
还有一个@app.before_first_request:表示,当程序运行起来,第一个请求来的时候就只执行一次,下次再来就不会在执行了
Flask【第2篇】:Flask基础的更多相关文章
- Flask最强攻略 - 跟DragonFire学Flask - 第六篇 Flask 中内置的 Session
Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...
- Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法
是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...
- flask 第六篇 flask内置的session
Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...
- Flask最强攻略 - 跟DragonFire学Flask - 第三篇 Flask 中的 request 之 先知道有这么个东西
每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前后端的交互 基于HTML + Flask 写一 ...
- Flask最强攻略 - 跟DragonFire学Flask - 第七篇 Flask 中路由系统
Flask中的路由系统其实我们并不陌生了,从一开始到现在都一直在应用 @app.route("/",methods=["GET","POST" ...
- 第一篇 Flask基础篇之(配置文件,路由系统,模板,请求响应,session&cookie)
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...
- 第二篇 Flask基础篇之(闪现,蓝图,请求扩展,中间件)
本篇主要内容: 闪现 请求扩展 中间件 蓝图 写装饰器,常用 functools模块,帮助设置函数的元信息 import functools def wrapper(func): @functools ...
- 第三篇 Flask 中的 request
第三篇 Flask 中的 request 每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前 ...
- 第二篇 Flask 中的 Render Redirect HttpResponse
第二篇 Flask 中的 Render Redirect HttpResponse 1.Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返 ...
- 第九篇 Flask 中的蓝图(BluePrint)
第九篇 Flask 中的蓝图(BluePrint) 蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? ...
随机推荐
- C语言指令数组名和数组名取地址
以下C语言指令:int a[5] = {1, 3, 5, 7, 9}; int *p = (int *)(&a + 1); printf("%d, %d", *(a + 1 ...
- nginx启动脚本和配置文件
1.编写Nginx启动脚本,并加入系统服务 vim /etc/init.d/nginx并在其中写入如下内容:#!/bin/bash# chkconfig: - 30 21# description: ...
- 算法初级(scala)
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/two-sum 1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为 ...
- 梳理检测论文-Refinement Neural Network
Single-Shot Refinement Neural Network for Object Detection 目录 1. motivation 2. RefineDet 解析(Network ...
- 005 gcc 的简单使用
0. 前言 本文主要讲关于 gcc 的几种编译方式 不妨设文件名为 test.c 1. 方法一 $ gcc test.c (Windows OS)编译成功的话,没有回馈,在 test.c 所在的文件夹 ...
- 深入.NET平台和C#编程的错题
29)有如下C# 代码,则下面选项中说法正确的是(BC).public class A { } Person public class B : A { } StudentA a = new A( ...
- iview报错[Vue warn]: Error in render: "TypeError: ctx.injections.tableRoot.$scopedSlots[ctx.props.column.slot] is not a function"
原因是我使用了iview的<Table>组件,我给Table组件的columns中定义了4个含有slot的列,但是实际在<Table>中只使用了其中3个,导致的报错. 也就是说 ...
- P2010回文日期
这道题是2016年普及组的题,难度等级为普及-. 这道题仍然是个模拟题.有两种策略:1.枚举回文,看日期是否存在2.枚举日期,看是否是回文.显然,前者要快很多,并且准确.本蒟蒻第一次便使用了后者,bu ...
- linux获取外网ip
引言:目前获取ip的方法中,ifconfig和ip获取函数得到的都是内网ip.有时候需要获取外网ip,目前通用的做法,是向外部服务器发送请求,解析外部服务器响应,从而得到的自己的外网ip.linux下 ...
- Kotlin学习(5)类型系统
可空性(避免空指针异常) /* *这个函数的参数代表传入一个String类型变量的实例,这代表它不可以为空 */ fun a(str:String){ println(str) } //这样调用a() ...