Flask学习

Flask学习



Flask 中文文档地址
https://dormousehole.readthedocs.io/en/latest/index.html

一、快速入门

示例:最简单的应用

from flask import Flask
app = Flask(__name__) # 创建flask的app

@app.route("/") #创建视图函数,利用装饰器可以配置路由
def hello():
    return "Hello World!"
if __name__ == "__main__":
    app.run()

二、知识点

1. 配置文件

代码如下(示例):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文件名称")
        如:
            settings.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})
        字典格式
 
**方式三:** 
	创建mysettings.py文件
    app.config.from_object("mysettings")
 
        app.config.from_object('mysettings.TestingConfig')
 
        mysettings.py
 
            class Config(object):
                DEBUG = False
                TESTING = False
                DATABASE_URI = 'sqlite://:memory:'
 
            class ProductionConfig(Config):
                DATABASE_URI = 'mysql://user@localhost/foo'
 
            class DevelopmentConfig(Config):
                DEBUG = True
 
            class TestingConfig(Config):
                TESTING = True
 
        PS: 从sys.path中已经存在路径开始写

2. 路由

使用 route() 装饰器来把函数绑定到 URL:

from markupsafe import escape

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return f'User {escape(username)}'

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return f'Post {post_id}'

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return f'Subpath {escape(subpath)}'

HTTP 方法

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_the_login()
    else:
        return show_the_login_form()

3. 视图

#CBV视图
from flask import Flask,url_for,views
#-----------------------------------------------------
app=Flask(__name__)               #装饰器

def auth(func):
    print('我在上面')
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner
#--------------------------------------------------------
class IndexView(views.MethodView):  #CBV视图
    methods=['GET']                #允许的http请求方法(改CBV只允许GET方法)
    decorators = [auth,]            #每次请求过来都加auth装饰器

    def get(self):
        return 'Index.GET'
    def post(self):
        return 'Index.POST'

app.add_url_rule('/index/',view_func=IndexView.as_view(name='name1')) #(name='name1'反向生成url别名


if __name__ == '__main__':
    app.run()


4. 模板

Jinja2文档 http://docs.jinkan.org/docs/jinja2/

<title>{% block title %}{% endblock %}</title>
<ul>
{% for user in users %}
 <li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>

5. 蓝图

蓝图的基本概念是:在蓝图被注册到应用之后,所要执行的操作的集合。当分配请求 时, Flask 会把蓝图和视图函数关联起来,并生成两个端点之前的 URL 。

from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound

simple_page = Blueprint('simple_page', __name__,
                        template_folder='templates')

@simple_page.route('/', defaults={'page': 'index'})
@simple_page.route('/<page>')
def show(page):
    try:
        return render_template(f'pages/{page}.html')
    except TemplateNotFound:
        abort(404)

注册蓝图

from flask import Flask
from yourapplication.simple_page import simple_page

app = Flask(__name__)
app.register_blueprint(simple_page)

6. 中间件

请求扩展
① before_request
类比django中间件中的process_request,在请求收到之前绑定一个函数做一些事情

#基于它做用户登录认证
@app.before_request
def process_request(*args,**kwargs):
    if request.path == '/login':
        return None
    user = session.get('user_info')
    if user:
        return None
    return redirect('/login')

② after_request
类比django中间件中的process_response,每一个请求之后绑定一个函数,如果请求没有异常

@app.after_request
def process_response1(response):
    print('process_response1 走了')
    return response

③ before_first_request
第一次请求时,跟浏览器无关

@app.before_first_request
def first():
    pass

④ teardown_request

每一个请求之后绑定一个函数,即使遇到了异常

@app.teardown_request 
def ter(e):
    pass

⑤ errorhandler
路径不存在时404,服务器内部错误500

Copy@app.errorhandler(404)
def error_404(arg):
    return "404错误了"

⑥ template_global
标签

Copy@app.template_global()
def sb(a1, a2):
    return a1 + a2
#{{sb(1,2)}}

⑦ template_filter
过滤器

Copy@app.template_filter()
def db(a1, a2, a3):
    return a1 + a2 + a3
#{{ 1|db(2,3)}}

总结

  • 重点掌握before_request和after_request
  • 注意有多个的情况,执行顺序
  • before_request请求拦截后(也就是有return值),response所有都执行
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello World!'

# 模拟中间件
class Md(object):
    def __init__(self, old_wsgi_app):
        self.old_wsgi_app = old_wsgi_app

    def __call__(self, environ, start_response):
        print('开始之前')
        ret = self.old_wsgi_app(environ, start_response)
        print('结束之后')
        return ret


if __name__ == '__main__':
    # 1.我们发现当执行app.run方法的时候,最终执行run_simple,最后执行app(),也就是在执行app.__call__方法
    # 2.在__call__里面,执行的是self.wsgi_app().那我们希望在执行他本身的wsgi之前做点事情。
    # 3.所以我们先用Md类中__init__,保存之前的wsgi,然后我们用将app.wsgi转化成Md的对象。
    # 4.那执行新的的app.wsgi_app,就是执行Md的__call__方法。
    # 5.把原来的wsgi_app替换为自定义的,

    app.wsgi_app = Md(app.wsgi_app)
    app.run()   

7. 相关组件

Flask-SQLalchemy:操作数据库;

Flask-migrate:管理迁移数据库;

Flask-Mail:邮件;

Flask-WTF:表单;

Flask-Bable:提供国际化和本地化支持,翻译;

Flask-script:插入脚本;

Flask-Login:认证用户状态;

Flask-OpenID:认证;

Flask-RESTful:开发REST API的工具;

Flask-Bootstrap:集成前端Twitter Bootstrap框架;

Flask-Moment:本地化日期和时间;

Flask-Admin:简单而可扩展的管理接口的框架

扩展列表:http://flask.pocoo.org/extensions/

中文文档(http://docs.jinkan.org/docs/flask/)

英文文档(http://flask.pocoo.org/docs/0.11/)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值