Flask基础

知识点回顾

1、flask依赖wsgi,实现wsgi的模块:wsgiref,werkzeug,uwsgi

2、实例化Flask对象,里面是有参数的

  1. app = Flask(__name__,template_folder='templates',static_url_path='/xxxxxx')

3、两种添加路由的方式

  1. 方式一:
  2. @app.route('/xxxx') # @decorator
  3. def index():
  4. return "Index"
  5. 方式二:
  6. def index():
  7. return "Index"
  8. app.add_url_rule('/xxx', "n1", index) #n1是别名 

4、添加路由关系的本质

  将url和视图函数封装成一个Rule对象)添加到Flask的url_map字段中

5、Flask中装饰器应用

  1. from flask import Flask,render_template,request,redirect,session
  2. app = Flask(__name__)
  3. app.secret_key = "sdsfdsgdfgdfgfh"
  4.  
  5. def wrapper(func):
  6. def inner(*args,**kwargs):
  7. if not session.get("user_info"):
  8. return redirect("/login")
  9. ret = func(*args,**kwargs)
  10. return ret
  11. return inner
  12.  
  13. @app.route("/login",methods=["GET","POST"])
  14. def login():
  15. if request.method=="GET":
  16. return render_template("login.html")
  17. else:
  18. # print(request.values) #这个里面什么都有,相当于body
  19. username = request.form.get("username")
  20. password = request.form.get("password")
  21. if username=="haiyan" and password=="123":
  22. session["user_info"] = username
  23. # session.pop("user_info") #删除session
  24. return redirect("/index")
  25. else:
  26. # return render_template("login.html",**{"msg":"用户名或密码错误"})
  27. return render_template("login.html",msg="用户名或者密码错误")
  28.  
  29. @app.route("/index",methods=["GET","POST"])
  30. @wrapper
  31. def index():
  32. # if not session.get("user_info"):
  33. # return redirect("/login")
  34. return render_template("index.html")
  35.  
  36. if __name__ == '__main__':
  37. app.run(debug=True) 

5、请求响应相关

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

flask配置文件

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

配置文件

一、路由系统

1、可传入参数:

  1. @app.route('/user/<username>') #常用的 不加参数的时候默认是字符串形式的
  2. @app.route('/post/<int:post_id>') #常用的 #指定int,说明是整型的
  3. @app.route('/post/<float:post_id>')
  4. @app.route('/post/<path:path>')
  5. @app.route('/login', methods=['GET', 'POST'])

常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:

  1. DEFAULT_CONVERTERS = {
  2. 'default': UnicodeConverter,
  3. 'string': UnicodeConverter,
  4. 'any': AnyConverter,
  5. 'path': PathConverter,
  6. 'int': IntegerConverter,
  7. 'float': FloatConverter,
  8. 'uuid': UUIDConverter,
  9. }

2、反向生成URL: url_for

endpoint("name")   #别名,相当于django中的name

反向解析需要导入:

  1. from flask import Flask, url_for
  1. @app.route('/index',endpoint="xxx") #endpoint是别名
  2. def index():
  3. v = url_for("xxx")
  4. print(v)
  5. return "index"
  6.  
  7. @app.route('/zzz/<int:nid>',endpoint="aaa") #endpoint是别名
  8. def zzz(nid):
  9. v = url_for("aaa",nid=nid)
  10. print(v)
  11. return "index2"

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

  1. @app.routeapp.add_url_rule参数:
  2. rule, URL规则
  3. view_func, 视图函数名称
  4. defaults=None, 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
  5. endpoint=None, 名称,用于反向生成URL,即: url_for('名称')
  6. methods=None, 允许的请求方式,如:["GET","POST"]
  7.  
  8. strict_slashes=None, URL最后的 / 符号是否严格要求,
  9. 如:
  10. @app.route('/index',strict_slashes=False),
  11. 访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
  12. @app.route('/index',strict_slashes=True)
  13. 仅访问 http://www.xx.com/index
  14. redirect_to=None, 重定向到指定地址
  15. 如:
  16. @app.route('/index/<int:nid>', redirect_to='/home/<nid>')

  17. def func(adapter, nid):
  18. return "/home/888"
  19. @app.route('/index/<int:nid>', redirect_to=func)
  20. subdomain=None, 子域名访问
  21. from flask import Flask, views, url_for
  22.  
  23. app = Flask(import_name=__name__)
  24. app.config['SERVER_NAME'] = 'haiyan.com:5000'
  25.  
  26. @app.route("/", subdomain="admin")
  27. def static_index():
  28. """Flask supports static subdomains
  29. This is available at static.your-domain.tld"""
  30. return "admin.xxx.com"
  31.  
  32.                             #动态生成
  33. @app.route("/dynamic", subdomain="<username>")
  34. def username_index(username):
  35. """Dynamic subdomains are also supported
  36. Try going to user1.your-domain.tld/dynamic"""
  37. return username + ".your-domain.tld"
  38.  
  39. if __name__ == '__main__':
  40. app.run()
  41. 所有的域名都得与IP做一个域名解析:
            如果你想通过域名去访问,有两种解决方式:
              方式一:
                1、租一个域名 haiyan.lalala
                2、租一个公网IP 49.8.5.62
                3、域名解析:
    haiyan.com 49.8.5.62
  1.             4、吧代码放在49.8.5.62这个服务器上,程序运行起来
                  用户可以通过IP进行访问
  1.           方式二:如果是自己测试用的就可以用这种方式。先在自己本地的文件中找
                 C:\Windows\System32\drivers\etc 找到HOST,修改配置
                然后吧域名修改成自己的本地服务器127.0.0.1
                加上配置:app.config["SERVER_NAME"] = "haiyan.com:5000"
  1.  

练习以上的参数

  1. redirect_to:直接重定向,原url有参数时,跳转是也得传参,注意:不用加类型
  1. #/old
  2. @app.route('/old/<int:nid>',redirect_to="/new/<nid>")
  3. def old(nid):
  4. return "old"
  5. # /new
  6. @app.route('/new/<int:nid>')
  7. def new(nid):
  8. return "new"
  1. # ============对url最后的/符号是否严格要求=========
  2. @app.route('/test',strict_slashes=True) #当为True时,url后面必须不加斜杠
  3. def test():
  4. return "aaaaaaaa"
  5. @app.route('/test',strict_slashes=False) #当为False时,url上加不加斜杠都行
  6. def test():
  7. return "aaaaaaaa"
  1. # =============== 子域名访问============
  2. @app.route("/static_index", subdomain="admin")
  3. def static_index():
  4. return "admin.bjg.com"
  5.  
  6. # ===========动态生成子域名===========
  7. @app.route("/index",subdomain='<xxxxx>')
  8. def index(xxxxx):
  9. return "%s.bjg.com" %(xxxxx,)

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

  1. from flask import Flask,url_for
  2.  
  3. app = Flask(__name__)
  4.  
  5. # 定义转换的类
  6. from werkzeug.routing import BaseConverter
  7. class RegexConverter(BaseConverter):
  8. """
  9. 自定义URL匹配正则表达式
  10. """
  11.  
  12. def __init__(self, map, regex):
  13. super(RegexConverter, self).__init__(map)
  14. self.regex = regex
  15.  
  16. def to_python(self, value):
  17. """
  18. 路由匹配时,匹配成功后传递给视图函数中参数的值
  19. :param value:
  20. :return:
  21. """
  22. return int(value)
  23.  
  24. def to_url(self, value):
  25. """
  26. 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
  27. :param value:
  28. :return:
  29. """
  30. val = super(RegexConverter, self).to_url(value)
  31. return val
  32.  
  33. # 添加到converts中
  34. app.url_map.converters['regex'] = RegexConverter
  35.  
  36. # 进行使用
  37. @app.route('/index/<regex("\d+"):nid>',endpoint='xx')
  38. def index(nid):
  39. url_for('xx',nid=123) #反向生成,就会去执行to_url方法
  40. return "Index"
  41.  
  42. if __name__ == '__main__':
  43. app.run()

二、视图函数

1、diango中的CBV模式

2、Flask中的CBV模式

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

3、Flask中的FBV模式

两种方式:

  1. 方式一:
  2. @app.route('/index',endpoint='xx')
  3. def index(nid):
  4. url_for('xx',nid=123)
  5. return "Index"
  6.  
  7. 方式二:
  8. def index(nid):
  9. url_for('xx',nid=123)
  10. return "Index"
  11.  
  12. app.add_url_rule('/index',index)

三、请求与响应

  1. 1 from flask import Flask
  2. 2 from flask import request
  3. 3 from flask import render_template
  4. 4 from flask import redirect
  5. 5 from flask import make_response
  6. 6
  7. 7 app = Flask(__name__)
  8. 8
  9. 9
  10. 10 @app.route('/login.html', methods=['GET', "POST"])
  11. 11 def login():
  12. 12
  13. 13 # 请求相关信息
  14. 14 # request.method
  15. 15 # request.args
  16. 16 # request.form
  17. 17 # request.values
  18. 18 # request.cookies
  19. 19 # request.headers
  20. 20 # request.path
  21. 21 # request.full_path
  22. 22 # request.script_root
  23. 23 # request.url
  24. 24 # request.base_url
  25. 25 # request.url_root
  26. 26 # request.host_url
  27. 27 # request.host
  28. 28 # request.files
  29. 29 # obj = request.files['the_file_name']
  30. 30 # obj.save('/var/www/uploads/' + secure_filename(f.filename))
  31. 31
  32. 32 # 响应相关信息
  33. 33 # return "字符串"
  34. 34 # return render_template('html模板路径',**{})
  35. 35 # return redirect('/index.html')
  36. 36
  37. 37 # response = make_response(render_template('index.html'))
  38. 38 # response是flask.wrappers.Response类型
  39. 39 # response.delete_cookie('key')
  40. 40 # response.set_cookie('key', 'value')
  41. 41 # response.headers['X-Something'] = 'A value'
  42. 42 # return response
  43. 43
  44. 44
  45. 45 return "内容"
  46. 46
  47. 47 if __name__ == '__main__':
  48. 48 app.run()
  1. from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
  2. from urllib.parse import urlencode,quote,unquote
  3. app = Flask(__name__)
  4.  
  5. @app.route('/index',endpoint='xx')
  6. def index():
  7. from werkzeug.datastructures import ImmutableMultiDict
      =================
  8. # get_data = request.args
  9. # get_dict = get_data.to_dict()
  10. # get_dict['xx'] = '18'
  11. # url = urlencode(get_dict)
  12. # print(url)
  13.   ====================
  14. # print(request.query_string)
  15. # print(request.args)
  16.   ==========================
  17. # val = "%E6%8A%8A%E5%87%A0%E4%B8%AA"
  18. # print(unquote(val)) #吧上面这样的数据转换成中文
  19. #
  20. # return "Index"
  21.  
  22. # return "Index"
  23. # return redirect()
  24. # return render_template()
  25. # return jsonify(name='alex',age='18') #相当于JsonResponse
  26.   =======================
  27. response = make_response('xxxxx') ##如果是返回更多的值,cookie,headers,或者其他的就可用它
  28. response.headers['xxx'] = '123123'
  29. return response
  30.  
  31. if __name__ == '__main__':
  32. # app.__call__
  33. app.run()

四、模板语法

1、为了防止xss攻击,加了验证,所以页面上显示字符串的形式,解决办法,有两种方式

  - 在后端Markup

  1. v5 = Markup("<input type='text' />")

  - 在前端

  1. {{ v4|safe }}

2、自定义方法

  1. def test(a,b):
  2. return a+b
  3.  
  4. @app.route('/index')
  5. def index():
  6. return render_template("index2.html"test=test)
  7.  
  8. index2.html
  9. <h1>{{ test(1,2) }}</h1>

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

template_global和template_filter

  1. @app.template_global()
  2. def sb(a1, a2):
  3. return a1 + a2
  4.  
  5. @app.template_filter()
  6. def db(a1, a2, a3):
  7. return a1 + a2 + a3
  1. 调用方式:{{sb(1,2)}} {{ 1|db(2,3)}}

4、模板继承:和django的一样。extents

5、宏:只有定义的东西在很多地方去使用的时候才去用它

  1. {% macro input(name, type='text', value='') %}
  2. <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
  3. {% endmacro %}
  4.  
  5. {{ input('n1') }}

练习:  

  1. 1 from flask import Flask,url_for,render_template,Markup
  2. 2 app = Flask(__name__)
  3. 3
  4. 4 def test(a,b):
  5. 5 return a+b
  6. 6
  7. 7 @app.template_global()
  8. 8 def sb(a1, a2):
  9. 9 return a1 + a2 + 100
  10. 10
  11. 11
  12. 12 @app.template_filter()
  13. 13 def db(a1, a2, a3):
  14. 14 return a1 + a2 + a3
  15. 15
  16. 16 @app.route('/index')
  17. 17 def index():
  18. 18 v1 = "字符串"
  19. 19 v2 = [11,22,33]
  20. 20 v3 = {"k1":"v3","sdf":"sdgfgf"}
  21. 21 v4 = "<input type='text' />"
  22. 22 v5 = Markup("<input type='text' />")
  23. 23 return render_template("index2.html",v1=v1,v2=v2,v3=v3,v4=v4,v5=v5,test=test)
  24. 24
  25. 25 if __name__ == '__main__':
  26. 26 app.run(debug=True)

模板语法

  1. 1 <!DOCTYPE html>
  2. 2 <html lang="en">
  3. 3 <head>
  4. 4 <meta charset="UTF-8">
  5. 5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. 6 <meta name="viewport" content="width=device-width">
  7. 7 <title>Title</title>
  8. 8 </head>
  9. 9 <body>
  10. 10 {{ v1 }}
  11. 11 <ul>
  12. 12 {% for foo in v2 %}
  13. 13 <li>{{ foo }}</li>
  14. 14 {% endfor %}
  15. 15 {{ v2.1 }}
  16. 16
  17. 17 {% for k,v in v3.items() %}
  18. 18 <li>{{ k }} {{ v }}</li>
  19. 19 {% endfor %}
  20. 20 {{ v3.k1 }}
  21. 21 {{ v3.get("k1") }}
  22. 22
  23. 23 {{ v4|safe }}
  24. 24 {{ v5 }}
  25. 25
  26. 26 <h1>{{ test(1,2) }}</h1>
  27. 27 <p>{{ sb(1,2) }}</p>
  28. 28 <p>{{ 1| db(2,3) }}</p>
  29. 29 </ul>
  30. 30 </body>
  31. 31 </html>

index2.html

五、session

除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。

  • 设置:session['username'] = 'xxx'

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

关于session的配置

  1. app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
  1. - session超时时间如何设置? 'PERMANENT_SESSION_LIFETIME': timedelta(days=31)
  1. 以下是跟session相关的配置文件
  1. """
  2. 'SESSION_COOKIE_NAME': 'session',
  3. 'SESSION_COOKIE_DOMAIN': None,
  4. 'SESSION_COOKIE_PATH': None,
  5. 'SESSION_COOKIE_HTTPONLY': True,
  6. 'SESSION_COOKIE_SECURE': False,
  7. 'SESSION_REFRESH_EACH_REQUEST': True, #是否每次都跟新
  8. 'PERMANENT_SESSION_LIFETIME': timedelta(days=31)
  1. 1 from flask import Flask, session, redirect, url_for, escape, request
  2. 2
  3. 3 app = Flask(__name__)
  4. 4
  5. 5 @app.route('/')
  6. 6 def index():
  7. 7 if 'username' in session:
  8. 8 return 'Logged in as %s' % escape(session['username'])
  9. 9 return 'You are not logged in'
  10. 10
  11. 11 @app.route('/login', methods=['GET', 'POST'])
  12. 12 def login():
  13. 13 if request.method == 'POST':
  14. 14 session['username'] = request.form['username']
  15. 15 return redirect(url_for('index'))
  16. 16 return '''
  17. 17 <form action="" method="post">
  18. 18 <p><input type=text name=username>
  19. 19 <p><input type=submit value=Login>
  20. 20 </form>
  21. 21 '''
  22. 22
  23. 23 @app.route('/logout')
  24. 24 def logout():
  25. 25 # remove the username from the session if it's there
  26. 26 session.pop('username', None)
  27. 27 return redirect(url_for('index'))
  28. 28
  29. 29 # set the secret key. keep this really secret:
  30. 30 app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

基本使用

  1. 1 pip3 install Flask-Session
  2. 2
  3. 3 run.py
  4. 4 from flask import Flask
  5. 5 from flask import session
  6. 6 from pro_flask.utils.session import MySessionInterface
  7. 7 app = Flask(__name__)
  8. 8
  9. 9 app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
  10. 10 app.session_interface = MySessionInterface()
  11. 11
  12. 12 @app.route('/login.html', methods=['GET', "POST"])
  13. 13 def login():
  14. 14 print(session)
  15. 15 session['user1'] = 'alex'
  16. 16 session['user2'] = 'alex'
  17. 17 del session['user2']
  18. 18
  19. 19 return "内容"
  20. 20
  21. 21 if __name__ == '__main__':
  22. 22 app.run()
  23. 23
  24. 24 session.py
  25. 25 #!/usr/bin/env python
  26. 26 # -*- coding:utf-8 -*-
  27. 27 import uuid
  28. 28 import json
  29. 29 from flask.sessions import SessionInterface
  30. 30 from flask.sessions import SessionMixin
  31. 31 from itsdangerous import Signer, BadSignature, want_bytes
  32. 32
  33. 33
  34. 34 class MySession(dict, SessionMixin):
  35. 35 def __init__(self, initial=None, sid=None):
  36. 36 self.sid = sid
  37. 37 self.initial = initial
  38. 38 super(MySession, self).__init__(initial or ())
  39. 39
  40. 40
  41. 41 def __setitem__(self, key, value):
  42. 42 super(MySession, self).__setitem__(key, value)
  43. 43
  44. 44 def __getitem__(self, item):
  45. 45 return super(MySession, self).__getitem__(item)
  46. 46
  47. 47 def __delitem__(self, key):
  48. 48 super(MySession, self).__delitem__(key)
  49. 49
  50. 50
  51. 51
  52. 52 class MySessionInterface(SessionInterface):
  53. 53 session_class = MySession
  54. 54 container = {}
  55. 55
  56. 56 def __init__(self):
  57. 57 import redis
  58. 58 self.redis = redis.Redis()
  59. 59
  60. 60 def _generate_sid(self):
  61. 61 return str(uuid.uuid4())
  62. 62
  63. 63 def _get_signer(self, app):
  64. 64 if not app.secret_key:
  65. 65 return None
  66. 66 return Signer(app.secret_key, salt='flask-session',
  67. 67 key_derivation='hmac')
  68. 68
  69. 69 def open_session(self, app, request):
  70. 70 """
  71. 71 程序刚启动时执行,需要返回一个session对象
  72. 72 """
  73. 73 sid = request.cookies.get(app.session_cookie_name)
  74. 74 if not sid:
  75. 75 sid = self._generate_sid()
  76. 76 return self.session_class(sid=sid)
  77. 77
  78. 78 signer = self._get_signer(app)
  79. 79 try:
  80. 80 sid_as_bytes = signer.unsign(sid)
  81. 81 sid = sid_as_bytes.decode()
  82. 82 except BadSignature:
  83. 83 sid = self._generate_sid()
  84. 84 return self.session_class(sid=sid)
  85. 85
  86. 86 # session保存在redis中
  87. 87 # val = self.redis.get(sid)
  88. 88 # session保存在内存中
  89. 89 val = self.container.get(sid)
  90. 90
  91. 91 if val is not None:
  92. 92 try:
  93. 93 data = json.loads(val)
  94. 94 return self.session_class(data, sid=sid)
  95. 95 except:
  96. 96 return self.session_class(sid=sid)
  97. 97 return self.session_class(sid=sid)
  98. 98
  99. 99 def save_session(self, app, session, response):
  100. 100 """
  101. 101 程序结束前执行,可以保存session中所有的值
  102. 102 如:
  103. 103 保存到resit
  104. 104 写入到用户cookie
  105. 105 """
  106. 106 domain = self.get_cookie_domain(app)
  107. 107 path = self.get_cookie_path(app)
  108. 108 httponly = self.get_cookie_httponly(app)
  109. 109 secure = self.get_cookie_secure(app)
  110. 110 expires = self.get_expiration_time(app, session)
  111. 111
  112. 112 val = json.dumps(dict(session))
  113. 113
  114. 114 # session保存在redis中
  115. 115 # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
  116. 116 # session保存在内存中
  117. 117 self.container.setdefault(session.sid, val)
  118. 118
  119. 119 session_id = self._get_signer(app).sign(want_bytes(session.sid))
  120. 120
  121. 121 response.set_cookie(app.session_cookie_name, session_id,
  122. 122 expires=expires, httponly=httponly,
  123. 123 domain=domain, path=path, secure=secure)

自定义Session

  1. 1 #!/usr/bin/env python
  2. 2 # -*- coding:utf-8 -*-
  3. 3 """
  4. 4 pip3 install redis
  5. 5 pip3 install flask-session
  6. 6
  7. 7 """
  8. 8
  9. 9
  10. 10 from flask import Flask, session, redirect
  11. 11 from flask.ext.session import Session
  12. 12
  13. 13
  14. 14 app = Flask(__name__)
  15. 15 app.debug = True
  16. 16 app.secret_key = 'asdfasdfasd'
  17. 17
  18. 18
  19. 19 app.config['SESSION_TYPE'] = 'redis'
  20. 20 from redis import Redis
  21. 21 app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='')
  22. 22 Session(app)
  23. 23
  24. 24
  25. 25 @app.route('/login')
  26. 26 def login():
  27. 27 session['username'] = 'alex'
  28. 28 return redirect('/index')
  29. 29
  30. 30
  31. 31 @app.route('/index')
  32. 32 def index():
  33. 33 name = session['username']
  34. 34 return name
  35. 35
  36. 36
  37. 37 if __name__ == '__main__':
  38. 38 app.run()

第三方session

六、blueprint,蓝图

七、闪现 : flash

session存在在服务端的一个字典里面,session保存起来,取一次里面还是有的,直到你删除之后才没有了

1、本质:flash是基于session创建的,flash支持往里边放值,只要你取一下就没有了,相当于pop了一下。不仅吧值取走,而且吧session里的东西去掉

2、闪现有什么用?

  1. from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
  2. app = Flask(__name__)
  3. app.secret_key ='sdfsdfsdf'
  4.  
  5. @app.route('/users')
  6. def users():
  7. # 方式一
  8. # msg = request.args.get('msg','')
  9. # 方式二
  10. # msg = session.get('msg')
  11. # if msg:
  12. # del session['msg']
  13. # 方式三
  14. v = get_flashed_messages()
  15. print(v)
  16. msg = ''
  17. return render_template('users.html',msg=msg)
  18.  
  19. @app.route('/useradd')
  20. def user_add():
  21. # 在数据库中添加一条数据
  22. # 假设添加成功,在跳转到列表页面时,显示添加成功
  23. # 方式一
  24. # return redirect('/users?msg=添加成功')
  25. # 方式二
  26. # session['msg'] = '添加成功'
  27. # 方式三
  28. flash('添加成功')
  29. return redirect('/users')
  30.  
  31. if __name__ == '__main__':
  32. app.run(debug=True)

八、扩展

1、在函数执行之前或函数执行之后做点事情

第一种:装饰器

第二种:flask里面的扩展,相当于django中的中间件

  1. from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
  2. app = Flask(__name__)
  3. app.secret_key ='sdfsdfsdf'
  4.  
  5. @app.before_request
  6. def process_request1():
  7. print('process_request1')
  8.  
  9. @app.after_request
  10. def process_response1(response):
  11. print('process_response1')
  12. return response
  13.  
  14. @app.before_request
  15. def process_request2():
  16. print('process_request2')
  17.  
  18. @app.after_request
  19. def process_response2(response): #参数也得有
  20. print('process_response2')
  21. return response #必须有返回值
  22.  
  23. @app.route('/index')
  24. def index():
  25. print('index')
  26. return 'Index'
  27.  
  28. @app.route('/order')
  29. def order():
  30. print('order')
  31. return 'order'
  32.  
  33. @app.route('/test')
  34. def test():
  35. print('test')
  36. return 'test'
  37.  
  38. if __name__ == '__main__':
  39. app.run()

运行结果:

还有一个@app.before_first_request:表示,当程序运行起来,第一个请求来的时候就只执行一次,下次再来就不会在执行了

Flask【第2篇】:Flask基础的更多相关文章

  1. Flask最强攻略 - 跟DragonFire学Flask - 第六篇 Flask 中内置的 Session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

  2. Flask最强攻略 - 跟DragonFire学Flask - 第四篇 Flask 中的模板语言 Jinja2 及 render_template 的深度用法

    是时候开始写个前端了,Flask中默认的模板语言是Jinja2 现在我们来一步一步的学习一下 Jinja2 捎带手把 render_template 中留下的疑问解决一下 首先我们要在后端定义几个字符 ...

  3. flask 第六篇 flask内置的session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

  4. Flask最强攻略 - 跟DragonFire学Flask - 第三篇 Flask 中的 request 之 先知道有这么个东西

    每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前后端的交互 基于HTML + Flask 写一 ...

  5. Flask最强攻略 - 跟DragonFire学Flask - 第七篇 Flask 中路由系统

    Flask中的路由系统其实我们并不陌生了,从一开始到现在都一直在应用 @app.route("/",methods=["GET","POST" ...

  6. 第一篇 Flask基础篇之(配置文件,路由系统,模板,请求响应,session&cookie)

    Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...

  7. 第二篇 Flask基础篇之(闪现,蓝图,请求扩展,中间件)

    本篇主要内容: 闪现 请求扩展 中间件 蓝图 写装饰器,常用 functools模块,帮助设置函数的元信息 import functools def wrapper(func): @functools ...

  8. 第三篇 Flask 中的 request

    第三篇 Flask 中的 request   每个框架中都有处理请求的机制(request),但是每个框架的处理方式和机制是不同的 为了了解Flask的request中都有什么东西,首先我们要写一个前 ...

  9. 第二篇 Flask 中的 Render Redirect HttpResponse

    第二篇 Flask 中的 Render Redirect HttpResponse   1.Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返 ...

  10. 第九篇 Flask 中的蓝图(BluePrint)

    第九篇 Flask 中的蓝图(BluePrint)   蓝图,听起来就是一个很宏伟的东西 在Flask中的蓝图 blueprint 也是非常宏伟的 它的作用就是将 功能 与 主服务 分开怎么理解呢? ...

随机推荐

  1. C语言指令数组名和数组名取地址

    以下C语言指令:int a[5] = {1, 3, 5, 7, 9}; int *p = (int *)(&a + 1); printf("%d, %d", *(a + 1 ...

  2. nginx启动脚本和配置文件

    1.编写Nginx启动脚本,并加入系统服务 vim /etc/init.d/nginx并在其中写入如下内容:#!/bin/bash# chkconfig: - 30 21# description: ...

  3. 算法初级(scala)

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/two-sum 1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为 ...

  4. 梳理检测论文-Refinement Neural Network

    Single-Shot Refinement Neural Network for Object Detection 目录 1. motivation 2. RefineDet 解析(Network ...

  5. 005 gcc 的简单使用

    0. 前言 本文主要讲关于 gcc 的几种编译方式 不妨设文件名为 test.c 1. 方法一 $ gcc test.c (Windows OS)编译成功的话,没有回馈,在 test.c 所在的文件夹 ...

  6. 深入.NET平台和C#编程的错题

    29)有如下C# 代码,则下面选项中说法正确的是(BC).public class A { }   Person public class B : A { }  StudentA a = new A( ...

  7. 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个,导致的报错. 也就是说 ...

  8. P2010回文日期

    这道题是2016年普及组的题,难度等级为普及-. 这道题仍然是个模拟题.有两种策略:1.枚举回文,看日期是否存在2.枚举日期,看是否是回文.显然,前者要快很多,并且准确.本蒟蒻第一次便使用了后者,bu ...

  9. linux获取外网ip

    引言:目前获取ip的方法中,ifconfig和ip获取函数得到的都是内网ip.有时候需要获取外网ip,目前通用的做法,是向外部服务器发送请求,解析外部服务器响应,从而得到的自己的外网ip.linux下 ...

  10. Kotlin学习(5)类型系统

    可空性(避免空指针异常) /* *这个函数的参数代表传入一个String类型变量的实例,这代表它不可以为空 */ fun a(str:String){ println(str) } //这样调用a() ...