首页 > 其他 > 详细

flask

时间:2019-11-13 00:06:44      阅读:85      评论:0      收藏:0      [点我收藏+]

一: flask简介

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

二: flask安装

pip3 install flask

三: flask基本使用

from flask import Flask

app = Flask(__name__)


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


if __name__ == __main__:
    app.run()

四: flask的四种响应

from flask import Flask, render_template, redirect, jsonify
# __name__表示所在文件
app = Flask(__name__)


@app.route(/index)
def index():
    # 直接返回字符串
    return "ok"

    # 返回HTML
    info = {name: "Tom", "age": 19, "gender": "male"}
    dict = {name: "Tom"}
    return render_template(index.html, name="hello world", info=info, name_dict=dict)

    # 跳转页面
    return redirect(/inner)

    # 返回json数据
    name_dict = [{name: "jason-gdx"}, {name: "tank-sb"}]
    return jsonify(name_dict)

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

if __name__ == __main__:
    app.run()

五: flak的配置文件

from flask import Flask

app = Flask(__name__)

# 配置文件
# app.debug = True
# app.secret_key = ‘123123‘

# 以字典的形式
# app.config[‘DEBUG‘] = True

# 以文件的方式
# app.config.from_pyfile(‘settings.py‘)

# 以类的形式(推荐使用, 比如: 上线和线下所用的配置文件不一样)
app.config.from_object(settings.DevelopmentConfig)


@app.route(/login)
def login():
    print("hello world")
    return ok


if __name__ == __main__:
    app.run()

  各种配置

 {
        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,
    }

六: 路由

  1. 创建路由的两种方式

from flask import Flask

app = Flask(__name__)

@app.route(/index)
def index():
    pass
# view_func必填
app.add_url_rule(/index, view_func=index)

if __name__ == __main__:
    app.run()

  2. 路由参数

from flask import Flask

app = Flask(__name__)

"""
rule: 路由
methods: 请求方式
endpoint: 起别名, 用于反向解析. url_for(‘index‘)
strict_slashes: 设置路由是否为严格模式, True为严格模式, False为非严格模式, 默认为True
redirect_to: 重定向到指定路径
"""
@app.route(/index, methods=["GET", "POST"], endpoint=index, strict_slashes=True, redirect_to=/login)
def index():
    return "index"

# app.add_url_rule(‘/index‘, view_func=index)
"""
self.add_url_rule(rule, endpoint, f, **potion)参数如下

self: Flask类产生的对象(app)
rule: 路由
endpoint: 取别名, 如果为空, 用当前的函数名
methods: 请求方式
view_func: 取别名指向的函数(请求该路径, 要响应的函数)
"""


@app.route(/login)
def login():
    return "login"


if __name__ == __main__:
    app.run()

 

  3. 路由跳转

from flask import Flask, url_for, redirect

app = Flask(__name__)
app.debug = True

def login():
    return "hello world"

app.add_url_rule(/login, view_func=login, endpoint=login)

def index():
    real_url = url_for(login)
    return redirect(real_url)

app.add_url_rule(/index, view_func=index)

if __name__ == __main__:
    app.run()

 

  4.自定义URL匹配正则表达式

"""
自定义URL匹配正则表达式
    1. 导入from werkzeug.routing import BaseConverter
    2. 先写一个类, 继承BaseConverter
        实现: __init__(), to_python(), to_url()方法
    3. app.url_map.converters[‘regex‘] = RegexConverter
    4. 我们在路由里面@app.route(‘/index/<regex("\d+"):nid>‘),regex1("正则表达式")
    5. regex("正则表达式")匹配出来的结果,传给to_python,一定要return
    6. 当我们做反向解析的解析的时候,我们的参数,会传递给to_url,return的结果才是我们拼接到我们路由上(真正的路由)
"""
from flask import Flask, url_for
from werkzeug.routing import BaseConverter

app = Flask(import_name=__name__)
app.debug = True

class RegexConverter(BaseConverter):

    def __init__(self, map, regex):
        super(RegexConverter, self).__init__(map)
        self.regex = regex

    def to_python(self, value):
        """
        路由匹配时, 匹配成功后传递给视图函数中参数的值
        value: 正则匹配出来的结果
        """
        print(value, type(value),2222222)
        return int(value)

    def to_url(self, value):
        """
        使用url_for反向解析生成URl时, 传递的参数经过该方法处理,
        返回的值用于生成URL中的参数
        """
        val = super(RegexConverter, self).to_url(value)
        print(val,3333333)
        return val

# ‘/index/<regex("\d+"):nid>‘ ":"后面不能有空格
app.url_map.converters[regex] = RegexConverter
@app.route(/index/<regex("\d+"):nid>, endpoint="index")
def index(nid):
    print(nid, type(nid),4444444)
    print(url_for(index, nid=999),55555555)
    # /index/999 55555555
    return "index"

if __name__ == __main__:
    app.run()

  5. 路由(起别名)

from flask import Flask, url_for, redirect, render_template

app = Flask(__name__)
app.debug = True

USERS = {
    1:{name:张三,age:18,gender:,text:"道路千万条"},
    2:{name:李四,age:28,gender:,text:"安全第一条"},
    3:{name:王五,age:18,gender:,text:"行车不规范"},
}

# @app.route(‘/detail/<int:nid>‘,methods=[‘GET‘],endpoint=‘detail‘)
def detail(nid):
    print(nid, type(nid))
    return render_template(index.html, info=USERS)

app.add_url_rule(/detail/<int:nid>, view_func=detail)


if __name__ == __main__:
    app.run()

 

  装饰器

 # 装饰器函数
 def route(self, rule, **options):

        def decorator(f):
            endpoint = options.pop("endpoint", None)
            self.add_url_rule(rule, endpoint, f, **options)
            return f

        return decorator

# 被装饰函数
@app.route(/login,methods=[POST, "GET"], endpoint=index)
def login():
    return "hello world"

装饰器: 先执行装饰器, 运行里面的代码, 返回一个函数名
        然后加括号, 把装饰器装饰的函数当成参数传递给函数,
        返回一个被装饰器装饰的同名函数

七: flask的CBV

from flask import Flask, url_for, views

app =Flask(__name__)
app.debug = True

# class IndexView(views.View):
#     methods = [‘GET‘, "POST"]
#
#     def dispatch_request(self):
#         print(‘index‘)
#         return "index"

class IndexView(views.MethodView):

    def get(self):
        return index get

    def post(self):
        return index post

app.add_url_rule(/index, view_func=IndexView.as_view(name=index))
"""
执行as_view()函数里面的view函数,
在执行MethodView类中的dispatch_request()函数,
根据请求的方式,进行任务的分发,默认get的请求.

为什么as_view()中药传参: 
    如果不传参, 都是view_func=view, 路由多要报错
    
相当于endpoint
"""

if __name__ == __main__:
    app.run()

八: .py文件中的标签渲染页面的两种方式

  .py文件

"""
一种: .py文件渲染标签, 导入Markup
二种: 前端页面{{ html|safe }}
"""
from flask import Flask, Markup, render_template

app = Flask(__name__)
app.debug = True

def func(st1, st2):
    return Markup(f"<h1>{st1} {st2}!</h1>")

@app.route(/index)
def index():
    html = "<h1>you are beautiful!</h1>"
    return render_template(index.html, func=func, html=html)

if __name__ == __main__:
    app.run()

  html页面

{{ func(‘hello‘, ‘world‘) }}
{{ html|safe}}

九: 请求与响应

from flask import Flask
from flask import request
from flask import make_response
from flask import render_template
from flask import redirect

  1. 请求

    request.args  # get请求提交的数据
    request.form  # post请求提交的数据
    request.values  # post和get提交的数据都在
    request.cookies  # 客户端携带cookie
    request.headers  # 请求头
    request.path  # 不带域名, 请求路径如: /index
    request.full_path  # 不带域名, 带参数的请求路径
    request.script_root
    request.url           带域名带参数的请求路径
    request.base_url      带域名请求路径
    request.url_root      域名
    request.host_url      域名
    request.host          127.0.0.1:500
    request.files
    obj = request.files[the_file_name]
    obj.save(/var/www/uploads/ + secure_filename(f.filename))

  2. 响应

    return "字符串"
    return render_template(html模板路径,**{})
    return redirect(/index.html)
    return jsonify({k1:v1})

    response = make_response(render_template(index.html))
    response.delete_cookie(key)
    response.set_cookie(key, value)
    response.headers[X-Something] = A value
   return response
    """
    1. 导入make_response
    2. response=make_response(4剑客)
    3. 操作response
    4. return response
    """

十: session和cookie

"""
session和cookie
app.session_interface这里面看 存session: 1. 调用save_session,将我们的session加密的val,读取配置文件[‘SESSION_COOKIE_NAME‘]得到key 2. 将1种的key,val存储到cookies 取session; 1. 获取request里面的cookies,获取里面key,这个key就是[‘SESSION_COOKIE_NAME‘],值就是加密的值 2. 对该值进行解密
""" from flask import Flask, session app = Flask(__name__) app.debug = True # 在浏览器存储的key名字 app.config[SESSION_COOKIE_NAME] = session # 秘钥 app.secret_key = ahsodhfb # @app.route(/index) def index(): session[hello] = world return ok # @app.route(/login) def login(): print(session.get(hello)) return I am fine if __name__ == __main__: app.run()

十一: 闪现

"""
闪现: 可用于记录日志

  1. 如果要用flash就必须设置app.secret_key = ‘asdfasdf‘
  2. 只能取一次,在取就没有了
  3. 我们可以通过 flash(‘普通信息‘,category="info"),对信息做分类
  4. get_flashed_messages(with_categories=True,category_filter=("error",)),with_categories以键值对的形式获取
    我们设置闪现,category_filter=("error",)进行分类信息的过滤

"""
from flask import Flask, flash, get_flashed_messages, jsonify

app = Flask(__name__)
app.debug = True
app.secret_key = xhjjjg

@app.route(/index)
def index():
  # flash(message, category) flash(
"超时错误", category="error") flash(普通信息,category="info") return "ssdsdsdfsd" @app.route(/inner) def inner(): # with_categories=False 表示只显示信息, 不显示分类 data = get_flashed_messages(with_categories=False, category_filter=("error", "info")) data1 = get_flashed_messages(with_categories=True, category_filter=("error", "info")) print(data) return "信息有误" if __name__ == __main__: app.run()

十二: 中间键

from flask import Flask

app = Flask(__name__)
app.debug = True

class MyMiddleware:

    def __init__(self, wsgi_app):
        self.wsgi_app = wsgi_app

    def __call__(self, environ, start_response):
        print(之前做操作)
        res = self.wsgi_app(environ, start_response)
        print(之后做操作)
        return res

@app.route(/index)
def index():
    return "ok"

if __name__ == __main__:
    # app.__call__()
    app.run()

十三: request扩展

  总结: 请求之前有return, 有return的函数执行, 响应函数不执行, 请求之后的函数执行,

     执行的顺序和django的中间件一样, 请求之后的函数必须return response

from flask import Flask, render_template, request

app = Flask(__name__)
app.debug = True

@app.before_request
def before1():
    print(request)
    print(请求1)
    return "111"

@app.before_request
def before2():
    print(request)
    print(请求2)
    return "222"

@app.after_request
def after1(response):
    print("我是请求之后1")
    return response

@app.after_request
def after2(response):
    print("我是请求之后2")
    return response


# 有没有异常都会执行该函数, 没有e为None, 有e为错误信息
@app.teardown_request
def tear(e):
    print(e)

# 捕获异常, 如果出现异常, 而且状态是@app.errorhandler(404)
# 可以做404页面
@app.errorhandler(404)
def error_404(args):
    print(args)
    return "404错误"

# 标签(前端页面向后端函数传数据): template_global
@app.template_global()
def add(a, b):
    return a + b
# {{ add(2, 3) }}

# 过滤器: template_filter
@app.template_filter
def filter(x, y, z):
    return x + y + z
# {{ 2|filter(3, 4) }}

@app.route(/index)
def index():
    print(视图函数)
    return render_template(index.html)

if __name__ == __main__:
    app.run()

 

 

flask

原文:https://www.cnblogs.com/zhuangshenhao/p/11838838.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!