flask 初识 (类似于django的框架)

 

官网地址点这里

我们的flask跟django类似,都是属于一个框架,这个框架更加微型,它里面的功能我们用django都能实现,

它更加轻量级,是基于python开发并且依赖jinja2模板和werkzeug WSGI服务的一个微型框架,对于werkzeug本质是socket服务端,其用于接收http请求并对请求进行预处理,然后触发flask框架,开发人员基于flask框架提供的功能对于请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinjia2模板来实现对模板的预处理,即将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器

 

flask麻雀虽小,五脏俱全,它的核心简单而易于扩展.flask不会替你做出太多决策,---比如使用何种数据库,而那些flask所选择的---比如使用何种模板引擎---则很容易替换.除此之外的一切都是可以自定义的.

默认情况下,flask不包含数据库抽象层,表单验证,或是其他任何已有多种库可以胜任的功能,然而,flask支持用扩展来给应用添加这些功能,如同是flask本身实现的一样,众多的扩展提供了数据库集成,表单验证,上传处理,各种各样的开发认证技术等功能.

  1 s8day123 
  2 
  3 内容回顾:
  4     1. 装饰器
  5         问题:什么是装饰器?
  6         问题:手写装饰器
  7         问题:装饰器都在哪里用过?
  8         
  9         import functools
 10 
 11         def wapper(func):
 12             @functools.wraps(func)
 13             def inner(*args,**kwargs):
 14                 return func(*args,**kwargs)
 15             return inner
 16         """
 17         1. 执行wapper函数,并将被装饰的函数当做参数。 wapper(index)
 18         2. 将第一步的返回值,重新赋值给  新index =  wapper(老index)
 19         """
 20         @wapper
 21         def index(a1):
 22             return a1 + 1000
 23 
 24         @wapper
 25         def order(a1):
 26             return a1 + 1000
 27 
 28 
 29         print(index.__name__)
 30         print(order.__name__)
 31     
 32     2. 谈谈你对面向对象的认识?
 33         - 封装:
 34             - 将同一类方法分为一类:方法封装到类中
 35             - 将方法中共同的参数封装到对象中:把共用值封装到对象中。
 36             
 37             情况:
 38                 a. BaseReponse            
 39                     def index(a1,a2,a3,a4,a5,a6,a7):
 40                         pass
 41                         
 42                     # 用户类实现
 43                     class Foo(object):
 44                         def __init__(self,a1,a2,a3,a4,a5,a6,a7):
 45                             self.a1 = a1
 46                             self.a2 = a2
 47                             self.a3 = a3
 48                             self.a4 = a4
 49                             self.a5 = a5
 50                             self.a6 = a6
 51                             self.a7 = a7
 52                             
 53                     def index(obj):
 54                         pass
 55                 b. 给了一些值,将数据加工: django 自定义分页
 56                     
 57                     class Foo(object):
 58                         def __init__(self,a1,a2,a3,a4,a5,a6,a7):
 59                             self.a1 = a1
 60                             self.a2 = a2
 61                             self.a3 = a3
 62                             self.a4 = a4
 63                             self.a5 = a5
 64                             self.a6 = a6
 65                             self.a7 = a7
 66                             
 67                         def 金条(self):
 68                             return self.a1 + self.a2
 69                             
 70                         def 手表(self):
 71                             return self.a1 + self.a7
 72                     
 73         
 74 
 75 今日内容:
 76     1. 配置文件
 77     2. 路由 *
 78     3. 视图函数
 79     4. 请求和响应 *
 80     5. 模板
 81     6. session * 
 82     
 83     8. 蓝图 blueprint *
 84     10. 中间件
 85     7. 闪现 
 86     
 87     
 88 内容详细:
 89     1. 配置文件
 90     
 91     2. 路由
 92         a. 添加路由的两种方式:
 93             from flask import Flask,render_template,redirect
 94             app = Flask(__name__)
 95 
 96             """
 97             1. 执行decorator=app.route('/index',methods=['GET','POST'])
 98             2. @decorator
 99                  - decorator(index)
100             """
101             # 路由方式一(*):
102             @app.route('/index',methods=['GET','POST'])
103             def index():
104                 return "Index"
105 
106             # 路由方式二:
107             def order():
108                 return 'Order'
109 
110             app.add_url_rule('/order',view_func=order)
111 
112 
113             if __name__ == '__main__':
114                 app.run()
115         b. endpoint(默认函数名)
116         c. 传参数
117             @app.route('/index/<int:nid>',methods=['GET','POST'])
118             def index(nid):
119                 print(nid,type(nid))
120                 
121                 url_for('index',nid=888)
122                 
123                 return "Index"
124         d. 自定义正则参数
125     
126                 from flask import Flask,render_template,redirect,url_for
127                 from werkzeug.routing import BaseConverter
128                 app = Flask(__name__)
129 
130 
131                 class RegexConverter(BaseConverter):
132                     """
133                     自定义URL匹配正则表达式
134                     """
135                     def __init__(self, map, regex):
136                         super(RegexConverter, self).__init__(map)
137                         self.regex = regex
138 
139                     def to_python(self, value):
140                         """
141                         路由匹配时,匹配成功后传递给视图函数中参数的值
142                         :param value:
143                         :return:
144                         """
145                         return int(value)
146 
147                     def to_url(self, value):
148                         """
149                         使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
150                         :param value:
151                         :return:
152                         """
153                         val = super(RegexConverter, self).to_url(value)
154                         return val
155 
156                 app.url_map.converters['xxx'] = RegexConverter
157 
158                 @app.route('/index/<xxx("\d+"):nid>',methods=['GET','POST'])
159                 def index(nid):
160                     print(nid,type(nid))
161                     v = url_for('index',nid=999) # /index/999
162                     print(v)
163                     return "Index"
164 
165                 if __name__ == '__main__':
166                     app.run()
167     
168         e. 其他参数
169             - 重定向
170                 from flask import Flask,render_template,redirect
171                 app = Flask(__name__)
172 
173                 @app.route('/index',methods=['GET','POST'],redirect_to='/new')
174                 def index():
175                     return "老功能"
176 
177                 @app.route('/new',methods=['GET','POST'])
178                 def new():
179                     return '新功能'
180 
181 
182                 if __name__ == '__main__':
183                     app.run()
184             
185                 PS: 前端重定向
186                     - meta
187                     - js 
188                     
189         重点:
190             - url
191             - methods 
192             - endpoint
193             - @app.route('/index/<int:nid1>/<int:nid2>/')
194             - url_for 
195     
196         
197     3. 
198         - cbv
199         - fbv
200         
201     4. 
202         request
203         response = make_response(....)
204         # 响应头
205         # cookie
206         return response 
207         
208     5. 模板
209     
210     6. session 
211         
212     7. 常见装饰器
213         - before_first_request
214         - before_request
215         - after_request
216         - errorhandler(404)
217         
218     8. 闪现
219     
220     9. 中间件
221     
222     10. 蓝图 
223     
224     
225     11. 补充:
226         - 项目依赖 pip3 install pipreqs
227             - 生成依赖文件:pipreqs ./ 
228             - 安装依赖文件:pip3 install -r requirements.txt 
229         - 什么是函数?什么是方法?
230         
231             from types import MethodType,FunctionType
232 
233             class Foo(object):
234                 def fetch(self):
235                     pass
236 
237             print(isinstance(Foo.fetch,MethodType))
238             print(isinstance(Foo.fetch,FunctionType)) # True
239 
240             obj = Foo()
241             print(isinstance(obj.fetch,MethodType)) # True
242             print(isinstance(obj.fetch,FunctionType))
243         
244         
245     
246     
247     
248     
249     
250     
251     
252     
概要

 

 

在python环境下安装flask:

pip3 install flask

一,基本使用

from flask import Flask

app = Flask(__name__)
app.debug=True  # 这里的debug设置为True就是出于开发模式,然后我们的flask程序就会自动重启

@app.route('/')
def hello():
    return "hello world"


if __name__ == '__main__':
    app.run()
# 我们的这个文件需要背会,要能够手写出来

 

 

from werkzeug.wrappers import Request, Response
from werkzeug.serving import run_simple


@Request.application
def hello(request):
    return Response("Hello World")


if __name__ == '__main__':
    # 请求一旦到来,执行第三个参数,即上面的函数名  参数()
    run_simple("localhost", 5000, hello)

 

二,配置文件

flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:

 {
        'DEBUG':                                get_debug_flag(default=False),  是否开启Debug模式
        'TESTING':                              False,                          是否开启测试模式
        'PROPAGATE_EXCEPTIONS':                 None,                          
        'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
        'SECRET_KEY':                           None,
        'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
        'USE_X_SENDFILE':                       False,
        'LOGGER_NAME':                          None,
        'LOGGER_HANDLER_POLICY':               'always',
        'SERVER_NAME':                          None,
        'APPLICATION_ROOT':                     None,
        '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,
        'MAX_CONTENT_LENGTH':                   None,
        'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
        'TRAP_BAD_REQUEST_ERRORS':              False,
        'TRAP_HTTP_EXCEPTIONS':                 False,
        'EXPLAIN_TEMPLATE_LOADING':             False,
        'PREFERRED_URL_SCHEME':                 'http',
        'JSON_AS_ASCII':                        True,
        'JSON_SORT_KEYS':                       True,
        'JSONIFY_PRETTYPRINT_REGULAR':          True,
        'JSONIFY_MIMETYPE':                     'application/json',
        'TEMPLATES_AUTO_RELOAD':                None,
    }




方式一:


  app.config['DEBUG']=True


  ps:由于Config对象本质上是字典,所以还可以使用app.config.update(...)


方式二:


  app.config.from_pyfile('python文件名称')


    如:

      setting.py

        DEBUG=True

      app.config.from_pyfile("settings.py")    

  app.config.from_envvar("环境变量名称")

环境变量的值为python文件名称,内部调用from_pyfile方法

 

app.config.from_json("json文件名称")

JSON文件名称,必须是json格式,因为内部会执行json.loads

app.config.from_mapping({"DEBUG":True})

字典格式

 

app.config.from_object("python类或类的路径")

app.config.from_object("pro_flask.settings.TestingConfig")

 

settings.py

class Config():

  DEBUG=False

  TESTING=False

  DATABASE_URL='sqlite://:memory:'

class ProductionConfig(Config):

  DATABASE_URL='mysql://user@localhost/foo'

class DevelopmentConfig(Config):

  DEBUG=True

class TestingConfig(Config):

  TESTING=True

ps:从sys.path中已经存在路径开始写

PS:settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录

 

三,路由系统

@app.route('/user/<username>')  这个<>括号里面这样写就是匹配字符串

@app.route('/post/<int:post_id>') 这个<>里面加上int:即是匹配数字
@app.route('/post/<float:post_id>') 匹配小数float:
@app.route("/post/<path:path>")  匹配路径path:
@app.route("/login/",methods=['GET','POST'])

常用路由即以上这些


路由的对应关系如下:
DEFAULT_CONVERTERS={
'defaut':UnicodeConverter,
'string':UnicodeConverter,
'any':AnyConverter,
'path':PathConverter,
'int':IntegerConverter,
'float':FloatConverter,
'uuid':UUIDConverter,
}

 

注册路由原理:

  1 def auth(func):
  2             def inner(*args, **kwargs):
  3                 print('before')
  4                 result = func(*args, **kwargs)
  5                 print('after')
  6                 return result
  7 
  8         return inner
  9 
 10         @app.route('/index.html',methods=['GET','POST'],endpoint='index')
 11         @auth
 12         def index():
 13             return 'Index'
 14 
 15  16         
 17         def index():
 18             return "Index"
 19 
 20         self.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])
 21         or
 22         app.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])
 23         app.view_functions['index'] = index
 24 
 25 
 26  27         def auth(func):
 28             def inner(*args, **kwargs):
 29                 print('before')
 30                 result = func(*args, **kwargs)
 31                 print('after')
 32                 return result
 33 
 34         return inner
 35 
 36         class IndexView(views.View):
 37             methods = ['GET']
 38             decorators = [auth, ]
 39 
 40             def dispatch_request(self):
 41                 print('Index')
 42                 return 'Index!'
 43 
 44         app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint
 45 
 46 
 47 
 48  49 
 50 
 51         class IndexView(views.MethodView):
 52             methods = ['GET']
 53             decorators = [auth, ]
 54 
 55             def get(self):
 56                 return 'Index.GET'
 57 
 58             def post(self):
 59                 return 'Index.POST'
 60 
 61 
 62         app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint
 63 
 64 
 65 
 66 
 67         @app.route和app.add_url_rule参数:
 68             rule,                       URL规则
 69             view_func,                  视图函数名称
 70             defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
 71             endpoint=None,              名称,用于反向生成URL,即: url_for('名称')
 72             methods=None,               允许的请求方式,如:["GET","POST"]
 73             
 74 
 75             strict_slashes=None,        对URL最后的 / 符号是否严格要求,
 76                                         如:
 77                                             @app.route('/index',strict_slashes=False),
 78                                                 访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
 79                                             @app.route('/index',strict_slashes=True)
 80                                                 仅访问 http://www.xx.com/index 
 81             redirect_to=None,           重定向到指定地址
 82                                         如:
 83                                             @app.route('/index/<int:nid>', redirect_to='/home/<nid>')
 84  85                                             def func(adapter, nid):
 86                                                 return "/home/888"
 87                                             @app.route('/index/<int:nid>', redirect_to=func)
 88             subdomain=None,             子域名访问
 89                                                 from flask import Flask, views, url_for
 90 
 91                                                 app = Flask(import_name=__name__)
 92                                                 app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
 93 
 94 
 95                                                 @app.route("/", subdomain="admin")
 96                                                 def static_index():
 97                                                     """Flask supports static subdomains
 98                                                     This is available at static.your-domain.tld"""
 99                                                     return "static.your-domain.tld"
100 
101 
102                                                 @app.route("/dynamic", subdomain="<username>")
103                                                 def username_index(username):
104                                                     """Dynamic subdomains are also supported
105                                                     Try going to user1.your-domain.tld/dynamic"""
106                                                     return username + ".your-domain.tld"
107 
108 
109                                                 if __name__ == '__main__':
110                                                     app.run()
111         
112 
113 a.注册路由原理
路由具体使用

 

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

 

四,模板:

模板的使用跟django别无二致,从模板继承到组件都是一样的逻辑

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     <h1>自定义函数</h1>
 9     {{ww()|safe}}
10 
11 </body>
12 </html>
13 
14 html
自定义模板
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from flask import Flask,render_template
 4 app = Flask(__name__)
 5  
 6  
 7 def wupeiqi():
 8     return '<h1>Wupeiqi</h1>'
 9  
10 @app.route('/login', methods=['GET', 'POST'])
11 def login():
12     return render_template('login.html', ww=wupeiqi)
13  
14 app.run()
15 
16 run.py
后端代码
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 
10     {% macro input(name, type='text', value='') %}
11         <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
12     {% endmacro %}
13 
14     {{ input('n1') }}
15 
16     {% include 'tp.html' %}
17 
18     <h1>asdf{{ v.k1}}</h1>
19 </body>
20 </html>
21 
22 其他
include标签

我们这里的Markup等同于我们的mark_safe

 

五,请求和相应

 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()
请求和相应

 

六,Session

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

设置:session['username']='peter'

删除:session.pop('username',None)

 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'
31 
32 基本使用
session基本使用

 

  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)
124 
125 自定义Session
自定义session

 

第三方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='6379')
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()
39 
40 第三方session
第三方session

 

七,蓝图:

蓝图用于为应用提供目录划分:

我们如果项目越做越大,文件就不能只是写到一个文件夹里面,我们需要做拆分,这个时候就需要蓝图来帮我们做这件事,

蓝图代码块:

我们先把文件逻辑整理一下:

在django里面我们的项目目录都是自动生成的,但是我们在flask里面都是需要自己去手动创建的

这里是我们创建目录的规则

创建一个文件夹,作为根目录pro_flask

在根目录里面创建一个文件夹,pro_flask

再创建一个templates文件夹里面存我们的HTML页面

还有views文件夹,存放我们的views视图

在根目录里面创建一个init文件,它是我们的程序一加载就会立即执行的文件

再在根目录里建立一个启动文件run.py

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from flask import Blueprint
 4 from flask import render_template
 5 from flask import request
 6 
 7 ac = Blueprint('account', __name__)
 8 @ac.route('/index')
 9 def index():
10     return 'wahaha'
account

 

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 from flask import Blueprint
4 
5 blog = Blueprint('blog', __name__)
6 
7 @blog.route('/hello')
8 def hi():
9     return 'hello'
blog

 

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 from flask import Blueprint
4 
5 user = Blueprint('user', __name__)
6 
7 @user.route('/home')
8 def home():
9     return 'home'
user

 

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from flask import Flask
 4 
 5 app = Flask(__name__,template_folder='templates',static_folder='statics',static_url_path='/static')
 6 aps=Flask(__name__)
 7 
 8 from .views import account
 9 from .views import blog
10 from .views.user import user
11 aps.register_blueprint(account.ac)
12 app.register_blueprint(account.ac)
13 app.register_blueprint(blog.blog)
14 app.register_blueprint(user)
__init__

 

1 from pro_flask import aps
2 from pro_flask import app
3 
4 
5 if __name__ == '__main__':
6     app.run()
7 if __name__ == '__main__':
8     aps.run
run.py启动文件

 

 

这里我们按照route参数里面的值,就能调用我们配置好的那些方法,让页面效果显示出来.

 大体的逻辑就是我们要建立一个run.py它要在项目目录的一级里面,然后它要引入我们的二级目录的init文件里面的Flask类所实例化出来的对象,在把run方法启动,就形成了启动文件

在这之前我们的启动项都和我们的视图以及路由在一个文件里面包含着,这里我们就把他们都拆分了,拆分之后我们需要让他们关联上,这个时候就需要我们的蓝图了,blueprint,它作为纽带来帮我们把启动项和视图部分给连接上,我们的视图里面要通过Blueprint类实例化出来一个对象,然后这个对象就像Flask实例化出来的对象那样去使用我们的route方法,在Blueprint类里面也有route方法,再回到我们的init文件里面去把我们的views文件夹里面的视图文件名给引入进来,然后再通过Flask类实例化出来的对象去注册blueprint类在view视图里面所实例化出来的对象,就有点类似于我们的admin里面对于model表的注册一样,这个功能解耦就是在init文件里面需要引入实例化对象,然后进行注册,这个步骤会稍稍有点繁琐,它主要就是把我们的视图和启动项给拆分开,就是为了这个功能的实现,所以把蓝图给引入了,通过它作为中间连接去跟我们的run()和视图关联

 

我们的蓝图创建流程先把上面的目录结构创建好,然后我们在init文件里面先把Flask引入,再把create_app函数创建好,把return值写上,然后把view视图里面的蓝图实例化对象给引入进来,把它注册上,register_blueprint用来注册蓝图实例化对象,写在create_app函数里面去.

这里既然引入了view视图,那么就需要取到视图里面把代码构建出来,引入蓝图,from flask import blueprints 然后用blueprints实例化出来一个对象(xxx=blueprints.Blueprint('xxx',__name__))跟我们的route连接,去做路由匹配然后就是路由和函数了,

再来就是我们的启动文件,manage.py里面的代码引入我们的init里面的create_app然后用它实例化出来一个对象,用这个对象去到main函数里面调用.run()方法,就可以启动程序了

 

八,闪现:

message是一个基于Session实现的用于保存数据的集合,其特点是:使用一次就删除

 1 from flask import Flask, flash, redirect, render_template, request, get_flashed_messages
 2 
 3         app = Flask(__name__)
 4         app.secret_key = 'some_secret'
 5 
 6 
 7         @app.route('/')
 8         def index1():
 9             messages = get_flashed_messages()
10             print(messages)
11             return "Index1"
12 
13 
14         @app.route('/set')
15         def index2():
16             v = request.args.get('p')
17             flash(v)
18             return 'ok'
19 
20 
21         if __name__ == "__main__":
22             app.run()
Message(闪现)

 

九,中间件:

 1 from flask import Flask, flash, redirect, render_template, request
 2  
 3 app = Flask(__name__)
 4 app.secret_key = 'some_secret'
 5  
 6 @app.route('/')
 7 def index1():
 8     return render_template('index.html')
 9  
10 @app.route('/set')
11 def index2():
12     v = request.args.get('p')
13     flash(v)
14     return 'ok'
15  
16 class MiddleWare:
17     def __init__(self,wsgi_app):
18         self.wsgi_app = wsgi_app
19  
20     def __call__(self, *args, **kwargs):
21  
22         return self.wsgi_app(*args, **kwargs)
23  
24 if __name__ == "__main__":
25     app.wsgi_app = MiddleWare(app.wsgi_app)
26     app.run(port=9999)
中间件

 

十,请求扩展:

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from flask import Flask, Request, render_template
 4 
 5 app = Flask(__name__, template_folder='templates')
 6 app.debug = True
 7 
 8 
 9 @app.before_first_request
10 def before_first_request1():
11     print('before_first_request1')
12 
13 
14 @app.before_first_request
15 def before_first_request2():
16     print('before_first_request2')
17 
18 
19 @app.before_request
20 def before_request1():
21     Request.nnn = 123
22     print('before_request1')
23 
24 
25 @app.before_request
26 def before_request2():
27     print('before_request2')
28 
29 
30 @app.after_request
31 def after_request1(response):
32     print('before_request1', response)
33     return response
34 
35 
36 @app.after_request
37 def after_request2(response):
38     print('before_request2', response)
39     return response
40 
41 
42 @app.errorhandler(404)
43 def page_not_found(error):
44     return 'This page does not exist', 404
45 
46 
47 @app.template_global()
48 def sb(a1, a2):
49     return a1 + a2
50 
51 
52 @app.template_filter()
53 def db(a1, a2, a3):
54     return a1 + a2 + a3
55 
56 
57 @app.route('/')
58 def hello_world():
59     return render_template('hello.html')
60 
61 
62 if __name__ == '__main__':
63     app.run()
请求扩展

 

 

 

示例:加上注释的代码块

先来个预热:

 1 class Foo():
 2     def __init__(self):
 3         self.__name='hello'
 4 """
 5 我们给类对象添加属性的时候也可以用这个方法去添加
 6 使用self.__属性名=属性值,然后我们要调用的时候就用对象名._类名__属性名去调用
 7 """
 8 hi=Foo()
 9 v=hi._Foo__name
10 print(v)
View Code

 

 1 """
 2 在不改变原函数调用基础上,对函数执行前后的信息进行自定义操作
 3 """
 4 import functools
 5 
 6 
 7 def wapper(func):
 8     # @functools.wraps(inner)  # 这里我们不能用inner,报错信息显示我们在定义前就调用了局部变量名inner,这是语法所不支持的
 9     @functools.wraps(func)  # 这里加上了functools就把我们的函数名还成他们自己本来的名字,而不是被我们的装饰器里面的inner所替代
10     def inner(*args, **kwargs):
11         return func(*args, **kwargs)
12 
13     return inner
14 
15 
16 @wapper
17 def index(a1):
18     return a1 + 20
19 
20 
21 @wapper
22 def order(a2):
23     return a2 + 30
24 
25 
26 # print(index.__name__)
27 # print(order.__name__)
28 
29 
30 def xx(yy=23):
31     def xbox(func):
32         def inner(*args, **kwargs):
33             if yy == 23:
34                 print('hello')
35                 res = func(*args, **kwargs)
36 
37                 return res
38 
39             else:
40                 print('you are field ')
41 
42         return inner
43 
44     return xbox
45 
46 
47 @xx(yy=23)
48 def index0(name):
49     print(name)
50 # index0('hi')
51 
52 
53 class File():
54     def __init__(self,a,b,c,):
55         self.a=a
56         self.b=b
57         self.c=c
58 
59     def file(self):
60         ...
61     def obj(self):
62         ...
63 
64 zz=File('he','she','them')
decorator

 

 1 from types import MethodType,FunctionType
 2 
 3 class Foo():
 4     def fetch(self):
 5         ...
 6 
 7 # print(isinstance(Foo.fetch,MethodType))  # False
 8 # print(isinstance(Foo.fetch,FunctionType))  # True
 9 """
10 如果是类调用这个函数,那么它就是一个函数,
11 但是如果是类实例化出来的对象调用这个函数,那么它就不是函数了,而是一个方法,对象里面的方法,
12 类调用函数
13 对象调用方法
14 """
15 fh=Foo()
16 # print(isinstance(fh.fetch,MethodType))  # True
17 # print(isinstance(fh.fetch,FunctionType))  # False
18 
19 
20 def h1():
21     ...
22 print(isinstance(h1,MethodType))
23 print(isinstance(h1,FunctionType))
method_or_function

 

 

闪现:

 1 from flask import Flask, session, flash, get_flashed_messages, request
 2 
 3 """
 4 first we need to put flash into session ,then we could fetch them out
 5 get_flashed_messages 
 6 original_code is here
 7 
 8 def get_flashed_messages(with_categories=False, category_filter=[]):
 9     
10     flashes = _request_ctx_stack.top.flashes
11     if flashes is None:
12         _request_ctx_stack.top.flashes = flashes = session.pop('_flashes') \
13             if '_flashes' in session else []
14     if category_filter:
15         flashes = list(filter(lambda f: f[0] in category_filter, flashes))
16     if not with_categories:
17         return [x[1] for x in flashes]
18     return flashes
19 
20 """
21 app = Flask(__name__)
22 app.secret_key = 'sfadf'  
23 #这里的密钥是必须要加上的,我们要定义一个固定的字符串,这样做是为了让#我们的cookie中的token能够一直被secret_key验证,从而保证我们的#cookie不会失效,这样cookie中存入的session值也会一直保留,验证可以顺利通过.
24 
25 
26 @app.route('/we')
27 def index():
28     flash('in me the tiger', category='wep')   # 这里的操作是把我们的数据存入到session里面,
29     flash('sniffs the rose', category='she')
30     flash('hello from outside', category='nobody')
31     return 'index'
32 
33 
34 @app.route('/she')
35 def root():
36     data = get_flashed_messages(with_categories=True, category_filter=['she'])
37     print(data)
38     return 'root '
39 
40 
41 if __name__ == '__main__':
42     app.run()
flash

 

请求以及相应:

 1 from flask import Flask, render_template, redirect, request, jsonify, make_response
 2 import json
 3 
 4 app = Flask(__name__)
 5 
 6 
 7 @app.route('/index', methods=['GET', 'POST'], redirect_to='/xxx')
 8 def index():
 9     """
10     print(request.method)
11     print(request.args)
12     print(request.form)
13     print(request.cookies)
14     print(request.headers)
15     print(1,request.path)
16     print(2,request.files)
17     print(3,request.values)
18     print(4,request.full_path)
19     print(5,request.script_root)
20     print(6,request.host)
21     print(7,request.host_url)
22     print(8,request.base_url)
23     print(9,request.url)
24     print(10,request.values)
25     跟相应相关的参数都在这里
26     :return:
27     """
28 
29     # obj = request.files['the_file_name']
30     # obj.save('/var/www/uploads/' + secure_filename(obj.filename))
31     # print(obj)
32     # return "in me the tiger"
33     # return json.dumps({})  # return jsonify({})
34     # return render_template('index.html')  # 我们只要在这里把前端模板文件名写上,
35     # 然后再在当前文件里面把templates文件夹创建好,它就会自动找到这个文件夹里面的文件去加载执行
36     # return redirect('/xxx')  # 这里重定向到另一个地址,我们可以在route里面直接加上参数也一样能达到这个效果
37 # 像这样写app.route('/index',methods=['GET','POST'],redirect_to='/xxx')
38     return 'hello world'
39 
40 
41 @app.route('/xxx', methods=['GET', 'POST'])
42 def hello():
43     return 'sniffs the rose'
44 
45 
46 if __name__ == '__main__':
47     app.run()
request_response
 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, initial-scale=1">
 7     <title>Title</title>
 8 </head>
 9 <body>
10 <h2>in me the tiger</h2>
11 </body>
12 </html>
template

 

路由:route

 1 from flask import Flask
 2 import functools  # 我们引入它放到装饰器里面是为了还原我们的被装饰的函数的名字
 3 
 4 aps = Flask(__name__)
 5 
 6 
 7 def wapper(func):
 8     @functools.wraps(func)  # 如果不加上这个还原我们被装饰的函数的名字,那么,装饰多个函数的时候
 9     def inner(*args, **kwargs):
10         print('before')
11 
12         return func(*args, **kwargs)
13 
14     return inner
15 
16 
17 @aps.route('/xx', methods=['GET', 'POST'])
18 @wapper
19 def just():
20     return 'Index'
21 
22 
23 @aps.route('/order', methods=['GET', 'POST'])
24 @wapper
25 def order():
26     return 'order'
27 
28 
29 if __name__ == '__main__':
30     aps.run()
route
 1 # 路由
 2 from flask import Flask,render_template,redirect
 3 app=Flask(__name__)
 4 
 5 # @app.route('/index',methods=['GET','POST'])  # 这里直接把路由写到我们的route里面
 6 def index():
 7     return 'hello'
 8 
 9 def order():
10     return 'world'
11 
12 app.add_url_rule('/order',view_func=order)  # 这种写法就类似于我们的django里面的url+视图,只不过是格式有点区别
13 app.add_url_rule('/index',view_func=index)
14 if __name__=='__main__':
15     app.run()
route(add_url)
 1 from flask import Flask, render_template, redirect, url_for, session
 2 from werkzeug.wrappers import Response
 3 app = Flask(__name__)
 4 
 5 
 6 @app.route('/index', methods=['GET', 'POST'], endpoint='f1')
 7 def index():
 8     k1 = url_for('f1')
 9     k2 = url_for('login1')  # 这里我们用的是反向解析的别名就跟我们的reverse一样,它默认是用我们的函数名,
10     # 如果我们没有定义endpoint就在这里把函数名作为参数加进去,如果我们定义了endpoint就使用我们定义好的
11     k3 = url_for('logout')
12     print(k1, k2, k3)
13     return 'index'
14 
15 
16 @app.route('/login0', methods=['GET', 'POST'], endpoint='login1')
17 def login():
18     return 'login'
19 
20 
21 @app.route('/logout1', methods=['GET', 'POST'])
22 def logout():
23     return 'logout'
24 
25 
26 if __name__ == '__main__':
27     app.__call__
28     app.run()
route_reverse
 1 from flask import Flask
 2 app=Flask(__name__)
 3 # 这里就是加上参数的路由配置,int:就是数字,通配所有数字,只要是数字我们都配在这个int:参数里,必须要有:,
 4 # 如果没有:就变成了字符串类型了,你即便传进去的是数字,浏览器传入后端的所有数据都是字符串,在后端这里定义什么类型接收就是什么类型
 5 # 如果加上了:然后我们还是用字符串传入后端,就会报错,页面显示不出来
 6 @app.route('/index/<int:dt>',methods=['GET',])
 7 def index(dt):
 8     print(dt,type(dt))
 9     return 'index'
10 
11 if __name__=='__main__':
12     app.run()
route带参数
 1 from flask import Flask, render_template, url_for
 2 from werkzeug.routing import BaseConverter
 3 
 4 app = Flask(__name__)
 5 
 6 
 7 class RegexConverter(BaseConverter):
 8     """
 9     自定义url匹配正则表达式
10     """
11 
12     def __init__(self, map, regex):
13         super(RegexConverter, self).__init__(map)
14         """
15         这里的to_url还有to_python是源码里面的方法,
16         def to_url(self, value):
17             return url_quote(value, charset=self.map.charset)
18         """
19         self.regex = regex
20 
21     def to_python(self, value):
22         """
23         路由匹配时,匹配成功后传递给视图函数中参数的值
24         :param value:
25         :return:
26         """
27         return int(value)
28 
29     def to_url(self, value):
30         """
31         使用url_for反向生成url时,传递的参数经过该方法处理,返回的值用于生成url中的参数
32         :param value:
33         :return:
34         """
35         val = super(RegexConverter, self).to_url(value)
36         return val
37 
38 
39 app.url_map.converters['jay'] = RegexConverter
40 
41 
42 # 这里我们要实现自定义加正则匹配的,url传参方式,就需要调用我们的源码里面的to_python还有to_url方法,我们自己重写这两个方法覆盖掉继承的源码的方法
43 # 这都是固定格式
44 @app.route('/index/<jay("\d+"):nt>', methods=['GET', 'POST'], endpoint='index90')
45 def index(nt):
46     print(nt, type(nt))
47     xx = url_for('index90',nt=9)  # 这里反向解析的变量名是我们route里面的endpoint里面的参数,
48     # 后面的参数是我们的route里面的url的参数名,
49     print(xx)
50     return 'hello world'
51 
52 
53 if __name__ == '__main__':
54     app.run()
route带参数升级版
 1 from flask import Flask, redirect
 2 
 3 app = Flask(__name__)
 4 
 5 
 6 @app.route('/index', methods=['GET', 'POST'])
 7 # 加上redirect_to就是跳转到该路由,
 8 
 9 def index():
10     return 'in me the tiger'
11 
12 
13 @app.route('/new', methods=['GET', 'POST'], redirect_to='/index')
14 def new():
15     return 'sniffs the rose'
16 
17 
18 if __name__ == '__main__':
19     app.run()
route_redirect(重定向)
 1 from flask import Flask, render_template, Response, redirect
 2 
 3 app = Flask(__name__)
 4 app.config['SERVER_NAME'] = 'sogo.com:5000'
 5 # 在源码内部我们实现了config['SERVER_NAME']跟subdomain的匹配,我们的subdomain里面的参数要跟下面的函数里面的参数保持一致,
 6 # 然后我们输入这个地址和函数的路由得到的是同一个页面
 7 
 8 # 这里是子域名访问,我们在config里面把子域名写上,然后输入上面我们配置项里面定义好的SERVER_NAME里面的值
 9 @app.route('/index', subdomain='<user>')
10 def index(user):
11     print(user)
12     return 'in me the tiger, sniffs the rose'
13 
14 
15 if __name__ == '__main__':
16     app.run()
route子域名

 

session:

 1 from flask import Flask, session
 2 
 3 app = Flask(__name__)
 4 app.secret_key = 'hello'
 5 
 6 
 7 @app.route('/x2')
 8 def index():
 9     session['k'] = 23
10     session['t'] = 40
11     del session['k']
12     return 'index'
13 
14 
15 @app.route('/x3')
16 def order():
17     print(session['t'])
18     return 'in me the tiger'
19 
20 
21 if __name__ == '__main__':
22     app.run()
session设置

 

配置文件:

建立两个文件夹,分开合作

 1 from flask import Flask
 2 
 3 app = Flask(__name__)
 4 # 配置文件
 5 app.config.from_object("settings.DevelopmentConfig")
 6 
 7 
 8 @app.route('/index', methods=['GET', "POST"])
 9 def index():
10     return "in me the tiger"
11 
12 
13 if __name__ == "__main__":
14     app.run()
启动文件
 1 class BaseConfig():
 2     DEBUG = True  # 默认我们的debug是True,就是会自动重启环境,否则我们都需要手动重启,
 3     SECRET_KEY = 'aghjksfdsl'
 4 
 5 
 6 # 生产环境
 7 class ProductionConfig(BaseConfig):
 8     DEBUG = False  # 这里是已经上线的状态,所以我们就把debug设置为False,就是面相用户的状态了
 9 
10 
11 # 开发环境
12 class DevelopmentConfig(BaseConfig):
13     ...
14 
15 
16 # 测试环境
17 class TestingConfig(BaseConfig):
18     ...
参数配置文件

 

decorator_特殊的装饰器(源码内部封装好的):

 1 from flask import Flask, render_template, redirect
 2 
 3 app = Flask(__name__)
 4 """
 5 这些request都是我们的源码里面封装好的,我们直接拿过来用就行
 6 """
 7 
 8 
 9 @app.before_request
10 def emmn():
11     print('before1')
12     return 'now i see you'  # 这里我们设了返回值之后就不会执行接下来的before_request了,就直接走到我们的after_request里面去
13 
14 
15 @app.before_request
16 def ennm():
17     print('before2')
18 
19 
20 @app.after_request
21 def hi(response):
22     print('after1')
23     return response
24 
25 
26 @app.after_request
27 def ho(response):
28     print('after2')
29     return response
30 
31 
32 @app.route('/z1')
33 def x1():
34     print('view1')
35     return 'view1'
36 
37 
38 # @app.route('/z2')
39 # def x2():
40 #     print('view2')
41 #     return 'view2'
42 
43 if __name__ == '__main__':
44     app.run()
decorator
 1 from flask import Flask, request, session, redirect
 2 # 通过我们的session加登录验证,我们在before_request函数里面把我们的校验条件
 3 app = Flask(__name__)
 4 app.secret_key = 'po'  # 这个secret_key是验证用的密钥,我们把它设置成一个固定的字符串,这样每一次验证的时候我们的cookie
 5 # 里面的token值就会一直被cookie验证,保证我们的cookie一直有效
 6 
 7 
 8 @app.before_request
 9 def check_login():
10     if request.path == '/login':
11         return None
12     user = session.get('user_info')  # 这里是验证条件,
13     if not user:
14         return redirect('/login')
15 
16 
17 @app.route('/login')
18 def login():
19     return 'view1'
20 
21 
22 @app.route('/pl')
23 def index():
24     session['user_info'] = 'opp'  # 我们这里把验证条件加上就可以通过验证了
25     print('view2')
26     return 'index'
27 
28 
29 if __name__ == '__main__':
30     app.run()
加session认证的decorator

 

模板_template:

 1 from flask import Flask, redirect, render_template, Markup
 2 
 3 app = Flask(__name__)
 4 
 5 
 6 @app.template_global()
 7 def sunshine(a, b):
 8     return a + b
 9 
10 
11 def gen_input(value):
12     # 这里就相当于是return了一个input标签,我们用markup就相当于是我们django里面的marksafe一样的效果
13     return Markup("<input value='%s'/>" % value)
14 
15 
16 @app.route('/who', methods=['GET', 'POST'])
17 def index():
18     arg = {
19         'h1': 23,
20         'h2': [90, 19],
21         'h3': {'name': 'alex', 'age': 30},
22         'h4': gen_input,  # 这个函数是上面定义好的,在这里放到模板里面用
23     }
24 
25     return render_template('index.html', **arg)
26 
27 
28 if __name__ == '__main__':
29     app.run()
template模板

 

 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, initial-scale=1">
 7     <title>base_template</title>
 8 </head>
 9 <body>
10 
11 <div>header</div>
12 <div>{% block content %}
13     {% endblock %}
14 </div>
15 <div>footer</div>
16 </body>
17 </html>
base母板继承
 1 {% extends 'base.html' %}
 2 
 3 {% block content%}
 4 
 5 <h2>{{h1}}</h2>
 6 <h3>{{h2.0}} &nbsp&nbsp {{h2[1]}}</h3>
 7 <!--我们取值在列表里面可以使用.索引值的方式,还可以通过[索引值的方式]-->
 8 <h4>{{h3.name}} &nbsp&nbsp {{h3['age']}}</h4>
 9 <!--字典里面取值也是通过.键的名字,还有['键的名字']-->
10 <span>{{h3.get('ag','in me the tiger')}}</span>
11 <!--还可以用get,-->
12 <h1>{{h4(37)}}</h1>
13 <h1>{{sunshine(20,30)}}</h1>
14 
15 {% endblock %}
继承母板的子版

 

视图:

CBV和FBV都在这里

 1 from flask import Flask, views
 2 
 3 app = Flask(__name__)
 4 import functools
 5 
 6 
 7 def wapper(func):
 8     @functools.wraps(func)  # 我们把函数名还原成原生的名字,就可以同时装饰多个函数
 9     def inner(*args, **kwargs):
10         print('before')
11         return func(*args, **kwargs)
12 
13     return inner
14 
15 
16 @app.route('/xxx', methods=['GET', 'POST'])
17 @wapper
18 def index():
19     return 'index'
20 
21 
22 class IndexView(views.MethodView):
23     methods = ['GET']
24 
25     decorators=[wapper,]
26     def get(self):
27         return 'index.GET'
28 
29     def post(self):
30         return 'index.post'
31 
32 
33 app.add_url_rule('/index', view_func=IndexView.as_view(name=""))  # 这里的name是固定属性用法,我们不能不写它,
34 # 它的值可以是空字符串(只能是字符串类型),但是必须要有它
35 
36 if __name__ == '__main__':
37     app.__call__
38     app.run()
views

 

 

中间件:

Middleware

 1 from flask import Flask
 2 """
 3 first we through the middleware 
 4 then we do the function 
 5 """
 6 app = Flask(__name__)
 7 app.secret_key = 'wthrtjk'
 8 
 9 
10 @app.route('/xx')
11 def index():
12     return 'index'
13 
14 
15 class Middleware():
16     def __init__(self, ol_wsgi_app):
17         self.old_wsgi_app = ol_wsgi_app
18 
19     def __call__(self, environ, start_response):
20         print('before')
21         from flask import session, request
22         fp = self.old_wsgi_app(environ, start_response)
23         print('after')
24         return fp
25 
26 if __name__ == '__main__':
27     app.wsgi_app = Middleware(app.wsgi_app)
28     app.run()
Middleware

 

posted @ 2018-04-24 23:42  dream-子皿  阅读(701)  评论(0)    收藏  举报