码迷,mamicode.com
首页 > 其他好文 > 详细

Flask初识

时间:2018-12-29 11:05:41      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:gconf   实现   hide   file   float   request请求   注册   注意   下载   

一、Flask初识

1、Flask介绍

Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug服务 ,模板引擎则使用 Jinja2 。
Flask使用 BSD 授权。

Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。
然而,Flask保留了扩增的弹性,可以用Flask-extension加入这些功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术

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

下载:
pip install flask

 

2、werkzeug

werkzeug类比django的wsgiref模块,封装了sorket

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)

 

二、基本的使用

1、FlaskDemo

from flask import Flask

# 实例化一个Flask对象 给它指定一个名字
app = Flask(__name__)  # 名字可以任意起,但是一般我们使用__name__


@app.route("/")  # 这是路由(http://127.0.0.1:5000/),就是用户访问的url(默认端口是5000)
def hello_world():  # 路由对应的处理函数
    return "hello World!"


if __name__ == __main__:
    app.run()  # 启动Flask

 

2、登录Demo

1. Flask代码
from flask import Flask, render_template, request, redirect


# template_folder就是指定你去哪个文件夹找你要渲染的html页面
# 默认是templates,可以修改,修改后你项目中存放html页面的文件夹名要对应更改
app = Flask(__name__, template_folder=templates)


@app.route("/login", methods=["GET", "POST"])  # method:指定允许请求的方式,不写-->默认只有GET
def login():
    if request.method == GET:
        return render_template(login.html)
    if request.method == POST:
        username = request.form.get(username)  # request.form:从表单获取数据
        pwd = request.form.get(pwd)
        if username == xiaoming and pwd == 123:
            return redirect(/index)  # redirect重定向
        else:
            return render_template(login.html, error=用户名或者密码错误)
            # 参数可以返回多个,用字典的形式返回,但是要解耦 **{}
            # return render_template("login.html", **{"error": "用户名或密码错误"})


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


if __name__ == __main__:
    app.run()


2. login.html
<body>
<form action="" method="post">

    <input type="text" name="username">
    <input type="text" name="pwd">
    <input type="submit">
    <p>{{error}}</p>
</form>
</body>


3. index.html
<body>
<h1>这是首页</h1>

<img src="/static/1.JPG" alt="">

</body>


4. 注意tempaltes以及static的配置
app = Flask(__name__, template_folder=templates, static_folder=static)
tempaltes是存放html页面的文件夹,可以在实例化Flask的时候通过参数template_folder指定文件夹的名字。
默认是tempaltes。

static是存放静态文件(图片、css、js等)的文件夹,可以在实例化Flask的时候通过参数static_folder指定文件夹的名字。
默认是static。

static_url_path=/xxx 它是一个路径,指向static的路径,也就是static路径的别名(不是真正的static路径),
如果设置了static_url_path,那么静态文件有两种方式可以访问到:
    "/项目路径/static/静态文件"
    "/xxx/静态文件"

 

3、配置文件

1. 配置文件信息
flask中的配置文件是一个flask.config.Config对象(继承字典)
默认配置为:
{
    ENV:                                  production生产环境
    DEBUG:                                get_debug_flag(default=False),  是否开启Debug模式
    TESTING:                              False,                          是否开启测试模式
    PROPAGATE_EXCEPTIONS:                 None,                          
    PRESERVE_CONTEXT_ON_EXCEPTION:        None,
    SECRET_KEY:                           None, session是否加盐
    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,
}


2. 修改flask配置信息的方式
Flask的配置信息是存在app.config里面的,
我们可以在实例化Flask对象之后,打印一下app.config来查看,
app.config是所有配置信息组成的字典。

方式一
既然是字典,就可以通过字典的方式进行修改:
通过app.config["xxx"] = xxx来更改配置信息,注意:config里面的键是大写的!!!
例如:
app.config["DEBUG"] = True
注意:不建议这么使用


方式二
可以直接通过Flask的实例化对象对配置进行修改,注意:这里是小写的
app.debug = True


方式三
通过app.config.from_object("python类或类的路径")来配置

1.flask项目代码
from flask import Flask


app = Flask(__name__)
app.config.from_object(settings.DEVConfig)
# app.config["DEBUG"] = True
# app.debug = True

@app.route(/)
def index():
    print(app.config)
    return "主页"


if __name__ == __main__:
    app.run()


2.settings.py
class DEVConfig(object):
    DEBUG = True


class TestingConfig(object):
    TESTING = True

 

4、路由系统

1. 路由参数
@app.route(/user/<username>)  # 参数是字符串类型
@app.route(/book/<int:id>)  # 指定参数是int类型
@app.route(/book/<float:id>)  # 指定参数是float类型
@app.route(/post/<path:path>)
注意:指定参数类型(int、float等)的时候,冒号两边不能有空格,即int:id,不能是int: id


# 路由默认支持的参数
DEFAULT_CONVERTERS = {
    default:          UnicodeConverter,  # 字符串
    string:           UnicodeConverter,  # 字符串
    any:              AnyConverter,  # 任意
    path:             PathConverter,  # 路径
    int:              IntegerConverter,  # 整数
    float:            FloatConverter,  # 小数
    uuid:             UUIDConverter,  # uuid
}


2. 路由的命名
通过给route设置endpoint参数,可以给路由进行命名,如果不设置endpoint,默认的路由命名是函数名
@app.route(/book/<int:id>, endpoint=book) # 默认是函数名字


3. 命名路由的反向解析
from flask import Flask, url_for
url_for("路由的名字", nid=32425)


4. 例子
from flask import Flask, redirect, url_for


app = Flask(__name__)


@app.route(/book/<int:id>, endpoint=book)
def book(id):
    print(id, type(id))
    return "BOOK"


@app.route(/index, endpoint=index)
def index():
    return redirect(url_for(book, id=1))


if __name__ == __main__:
    app.run()

 

5、模板

1. 跟Django比较,相同点与不同点
相同点:
  Flask模板的使用的是JinJa2模板,语法基本上跟Django无差别,只是在一些细节上有些不同。
  Django模板的基本使用可参考:
    https://www.cnblogs.com/Zzbj/p/9892169.html
    https://www.cnblogs.com/Zzbj/p/9898526.html

不同点:
  flask模板中函数执行要加括号,Django的模板使用函数是不需要括号的
  flask模板中字典的取值可以使用 . 点,也使用get,Django模板中字典取值只能使用 . 点
  flask模板中列表的取值可以使用 . 点,也使用[索引],Django模板中列表取值只能使用 . 点
  支持创建一个函数通过render_template页面的形式传递到模板中


2. 示例

技术分享图片
from flask import Flask, render_template


app = Flask(__name__)

book_list = [
    {"id": 1, "title": "三国演义"},
    {"id": 2, "title": "水浒传"},
    {"id": 3, "title": "西游记"},
    {"id": 4, "title": "红楼梦"},
]

name = ZBJ的图书
my_dict = {"age": 18}
my_list = [1, 2]

def my_func():
    return <h2>把自定义函数传到模板</h2>


@app.route(/book,)
def book():
    return render_template(book.html, **{book_list: book_list, name: name, my_dict: my_dict, my_list: my_list , my_func: my_func})


if __name__ == __main__:
    app.run()
python代码
技术分享图片
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>{{name}}</h1>
    <table>
        <thead>
            <tr>
                <th>title</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for book in book_list %}
                <tr>
                    <td>{{book.title}}</td>
                    <td>删除 | 编辑</td>
                </tr>
            {% endfor %}
        </tbody>

    </table>
    <hr>
    {{my_func()|safe}}
    <hr>
    字典get取值:{{my_dict.get("age", 0)}}
    <br>
    字典 . 点取值:{{my_dict.age}}
    <br>
    <hr>
    列表索引取值:{{my_list[0]}}
    <br>
    列表 . 点取值:{{my_list.1}}
    <hr>
</body>
</html>
模板代码

 

6、请求和响应

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

app = Flask(__name__)


@app.route(/login, methods=[GET, "POST"])
def login():
    """
    1、请求相关信息
    request.method            请求的方式
    request.args            请求的url的参数 ?
    request.form            form表单的数据
    request.values
    request.cookies            cookies
    request.headers            请求头
    request.path            请求的url路径(不含参数 ?)
    request.full_path        请求的url路径(包含参数 ?)
    request.script_root        脚本的地址
    request.url
    request.base_url
    request.url_root
    request.host_url
    request.host
    request.files            上传过来的文件数据
    文件的一些使用方法
    obj = request.files[‘the_file_name‘]  获取文件名
    obj.save(‘/uploads/‘ + secure_filename(f.filename))  把文件数据保存在服务器

    2、响应相关信息
    1. 这几种是把响应直接放在响应体里面,然后直接返回
    return "字符串"
    return render_template(‘html模板路径‘,**{})
    return redirect(‘/index.html‘)

    2. 下面这种是先封装响应对象,然后对响应对象做一些操作,再把响应对象返回
    response = make_response(render_template(‘index.html‘))  response是flask.wrappers.Response类型
    response.delete_cookie(‘key‘)  删除cookie
    response.set_cookie(‘key‘, ‘value‘)  设置cookie
    response.headers[‘X-Something‘] = ‘value‘  设置响应头
    return response  最后返回
    """
    return "看注释吧!"


if __name__ == __main__:
    app.run()

 

7、session

session对象,它允许你在不同请求间存储特定用户的信息。
它是在 Cookies 的基础上实现的,并且对 Cookies 进行加密,你需要设置一个密钥。

session的加密默认用的是md5的加密方式,它规定了必须加盐,这个盐secret_key在配置信息中可以设置。
通过配置信息的secret_key设置盐:
  app.secret_key = ‘嘿嘿嘿‘
  app.config[‘SECRET_KEY‘] = ‘嘿嘿嘿‘


设置session
  session[‘xxx‘] = ‘xxx‘

取session值
  session.get(‘xxx‘, ‘‘)

删除session
  session.pop(‘xxx‘, None)


示例
1. python代码

# python代码
from flask import Flask, session, redirect, url_for, request, render_template
# 注意:导入的时候session跟sessions是不同的,注意 s


app = Flask(__name__)
# session必须设置session加密的盐
app.secret_key = 嘿嘿嘿


@app.route(/login, methods=[GET, POST])
def login():
    if request.method == "POST":
        username = request.form.get(username)
        pwd = request.form.get(pwd)
        if username == xiaoming and pwd == 123:
            session[username] = username
            return redirect(url_for(index))
        return render_template(login.html, error="用户名或者密码错误")
    return render_template(login.html)


@app.route(/index)
def index():
    if session.get(username, ‘‘):
        return "用户已登录,这是首页"
    return "用户未登录,请去登录页面"


@app.route(/logout)
def logout():
    session.pop(username, None)
    return redirect(url_for(index))


if __name__ == __main__:
    app.run()

 

2. login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="" method="post">

    <input type="text" name="username">
    <input type="text" name="pwd">
    <input type="submit">
    <p>{{error}}</p>
</form>

</body>
</html>

 

8、flash

1、flash原理
flash是一个基于session实现的用于保存数据的集合,特点是使用一次就删除.一次的意思是一次请求的开始,请求的结束,
在这段时间是可以随便使用的,但是请求结束后,第二次请求进来的时候,就取不到值了。
它的原理:
  设置值的时候 session["xxx"] = value
  取值 session.pop("xxx")

注意:因为flash是基于session的,因此也要设置SECRET_KEY

设置方式一:
直接设置值
  flash(值1)
  flash(值2)

设置值:
  flash(‘小明‘)
  flash(‘小东‘)

取值:
  name = get_flashed_messages()   # [‘小明‘, ‘小东‘]
注意:
  flash是一个列表,多次flash设置值,都是append进一个列表的,
  取值的时候,就把那个列表取出来,然后把值清空,
  再次取值的时候,就只能取到一个空列表。

设置方式二:
给flash分类,flash有一个参数category,就是分类的意思,
不设置的话,所有flash都是message这个分类,我们可以根据需要给flash的值设置分类。

  flash(值1, 分类名1)
  flash(值2, 分类名2)

设置值:
  flash(‘小明‘, ‘ming‘)
  flash(‘小东‘)

取值:
  name1 = get_flashed_messages()   # [‘小明‘, ‘小东‘]
  name2 = get_flashed_messages(category_filter=[‘ming‘])   # [‘小明‘]


2、Demo
1. flash原理Demo

from flask import Flask, session


app = Flask(__name__)
app.secret_key = 雅蠛蝶


@app.route(/set)
def set():
    session[name] = 小明
    return "SET"


@app.route(/get)
def get():
    name = session.pop(name)
    print(name)
    return "GET"


if __name__ == __main__:
    app.run()

取了一次值后,下次去get,就取不到值了

 

2. flashDemo

from flask import Flask, flash, get_flashed_messages


app = Flask(__name__)
app.config[SECRET_KEY] = 雅蠛蝶


@app.route(/set)
def set_flash():
    flash(小明, ming)
    flash(小东)
    return "SET_FLASH"


@app.route(/get)
def get_flash():
    name1 = get_flashed_messages()
    print(name1)  # [‘小明‘, ‘小东‘]
    name2 = get_flashed_messages(category_filter=[ming])
    print(name2)  # [‘小明‘]
    return "GET_FLASH"


if __name__ == __main__:
    app.run()

 

9、中间件

9-1、小预习
Flask的中间件跟Django的不太一样,我们需要从源码去理解,
需要用到类的一些内置方法(双下方法):__init__、__call__

1. 类

class A():
    def __init__(self):
        print("init")

    def __call__(self, *args, **kwargs):
        print("call")

a = A()  # init
a()  # call
类加括号:实例化一个对象-->调用__init__方法
对象加括号:调用__call__方法

 

2. werkzeug启动flask项目的原理

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)
    
最后启动项目的是执行了run_simple这个方法,
这个方法有三个参数:
    localhost:域名
    5000:端口
    hello:函数名

意思就是:在这个域名这个端口,调用hello这个函数

 

9-2、app.run的源码基本流程
(werkzeug是我们封装sorket的地方~源码是从run_simple方法开始走的)

app.run():
  调用了werkzueg的run_simple方法 run_simple(host, port, self, **options)

  这个方法中是self是我们的app, 我们知道werkzeug会执行app()

  这是我们程序的入口,会执行我们app.__call__方法

  那现在如果我想在请求进来之前做一些事情,以及请求结束以后做一些事情

  那么就可以实现中间件的效果

app.run() -->
  run_simple(host, port, self, **options) -->
    self() --> app() --> app是Flask的实例化对象,因此会调用Flask这个类的__call__ -->
      __call__把app.wsgi_app执行后的结果返回了,return self.wsgi_app(environ, start_response)[self就是app],
      environ是请求来的最原生的数据-->
        也就是说,flask所有请求进来时,都会从Flask的__call__开始执行,
        我们只需在__call__这个方式的执行前后做一些事情,就可以实现中间件的功能了。

9-3、实现方式
1. 改源码(不建议使用)

def __call__(self, environ, start_response):
    """The WSGI server calls the Flask application object as the
    WSGI application. This calls :meth:`wsgi_app` which can be
    wrapped to applying middleware."""
    # return self.wsgi_app(environ, start_response)
    print("开始之前")
    ret = self.wsgi_app(environ, start_response)
    print("请求之后")
    return ret
    

 

2. 中间件类

from flask import Flask


app = Flask(__name__)


class Middleware(object):
    def __init__(self, old_call):
        self.old_call = old_call

    def __call__(self, *args, **kwargs):
        print(请求来之前做的事情)
        ret = self.old_call(*args, **kwargs)
        print(请求来到之后做的事情)
        return ret


app.wsgi_app = Middleware(app.wsgi_app)


if __name__ == __main__:
    app.run()
    # run_simple(host, port, self, **options)
    # run_simple执行了 self()
    # self = app
    # app() 执行Flask的__call__
    # __call__返回app.wsgi_app()的执行结果
    # 我重写了app.wsgi_app--> Middleware(app.wsgi_app)()

注意:通常我们不会这样去实现中间件,因为Flask中有一些特殊的装饰器能够帮我们实现中间件的功能,哈哈哈哈~~~

 

10、特殊的装饰器

需求:
  我们很多访问都是需要进行登录认证,那么在flask中如何实现登录认证的功能

1. 小预习

# python的装饰器
from functools import wraps
# 被装饰器装饰的函数名字会变成内部的函数名
# 我们需要给inner函数加个装饰器来修改inner函数的信息


def wrapper(func):
    @wraps(func)
    def inner(*args, **kwargs):
        ret = func(*args, **kwargs)
        return ret
    return inner


@wrapper
def index(x, y):
    return x + y


res = index(1, 2)
print(res)
print(index.__name__)

 

2. 使用python装饰器实现认证功能

给每个需要认证的函数都加上自定义的认证装饰器

from flask import Flask, session, redirect, url_for
from functools import wraps


app = Flask(__name__)
app.secret_key = 哈哈

# 实现登录 我们不可能每个视图函数都去获取session然后判断
# 我们可以利用装饰器
# 注意装饰器装饰完函数名的问题
# 注意装饰器执行顺序问题


# 实现认证的装饰器
def auth(func):
    @wraps(func)
    def inner(*args, **kwargs):
        if not session.get(username):
            return redirect(url_for(login))
        ret = func(*args, **kwargs)
        return ret
    return inner


@app.route(/login)
def login():
    session[username] = 小明
    return "登录成功"


@app.route(/logout)
def logout():
    session.pop(username)
    return "退出登录"


# 注意:app.route和auth装饰器的顺序不能乱,必须是先认证了成功后才放行
@app.route(/user)
@auth
def user():
    return "用户页面"


@app.route(/book)
@auth
def book():
    return "图书页面"


if __name__ == __main__:
    app.run()

 

3. Flask提供的特殊装饰器before_request
任何请求进来,都要先执行被before_request装饰的函数,
在这个函数进行认证,其他函数就不需要每个都加认证装饰器了。

from flask import Flask, session, redirect, url_for, request


app = Flask(__name__)
app.secret_key = 哈哈

# 任何请求进来,都要先执行这个函数
@app.before_request
def auth():
    if request.path == /login or request.path == /:
        # 如果是登录请求,直接放行
        return None
    if session.get(username, ‘‘):
        # 如果携带了session的请求,证明已经登录,放行
        return None
    # 否则,都跳转到登录页面
    return redirect(url_for(login))


@app.route(/login)
def login():
    session[username] = 小明
    return "登录成功"


@app.route(/logout)
def logout():
    session.pop(username)
    return "退出登录"


# 不需要加其他装饰器了
@app.route(/user)
def user():
    return "用户页面"


@app.route(/book)
def book():
    return "图书页面"


if __name__ == __main__:
    app.run()

 

11、flask常用的特殊装饰器

1. 请求第一次进来的时候执行
@app.before_first_request
第二次请求就不会执行了

2. 请求每次进来都执行
@app.before_request

3. 每次响应的时候执行
@app.after_request

4. 发生404的时候执行
@app.errorhandler(404)

5. 全局的函数,在所有html模板中都可以使用的函数,并且不需要传
@app.template_global()

6.模板的过滤器,在所有html模板中都可以使用的过滤器,并且不需要传
@app.template_filter()

 

7. Demo

技术分享图片
from flask import Flask, Request, render_template

app = Flask(__name__)
app.debug = True


@app.before_first_request
def before_first_request1():
    print(before_first_request1)


@app.before_first_request
def before_first_request2():
    print(before_first_request2)


@app.before_request
def before_request1():
    print(before_request1)


@app.before_request
def before_request2():
    print(before_request2)


@app.after_request
def after_request1(response):
    print(after_request1, response)
    return response


@app.after_request
def after_request2(response):
    print(after_request2, response)
    return response


@app.errorhandler(404)
def page_not_found(error):
    return This page does not exist, 404


@app.template_global()
def jiafa(a1, a2):
    # 在所有模板在都可以这样使用 {{ jiafa(1, 2) }}
    return a1 + a2


@app.template_filter()
def db(data):
    # 在所有模板在都可以这样使用 {{ "hello"|db() }}
    # 这里data就是hello
    return data[::2]


@app.route(/)
def hello_world():
    return render_template(hello.html)


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

 

8. 注意
这几个装饰器跟Django的中间件很像,也有执行顺序的
request请求进来,顺序执行
response响应出去,倒序执行

超级注意
  !!! before_request有返回值的时候还会按顺序执行after_request
  !!! Django<=1.9的版本 当process_request有返回值的时候跟flask是一样的

 

12、视图

1. route原理

之前我们的视图都是FBV,那么我们的CBV要怎么实现呢?
实现CBV之前我们要看一下路由的实现原理
我们看下@app.route("/xx")做了什么:

    首先这是一个带参数的装饰器,那么带参数的装饰器执行顺序是什么样的
        1,先去掉@ 执行route("/xx")得到返回值
        2,再拿返回值加上@符号去装饰接下来的函数

route源码
    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

从源码中可以看出:
    route函数返回了decorator函数,也就是说实际上是用decorator这个函数去装饰我们的视图函数的
    f就是我们的视图函数,
    decorator调用了add_url_rule方法
    endpoint默认取函数名!
    两个函数不能用一个endpoint !


那么实际上路由的实现原理:
from flask import Flask


app = Flask(__name__)


def index():
    return "index"


app.add_url_rule("/", endpoint="index", view_func=index)


if __name__ == __main__:
    app.run()

 

2. CBV

# CBV需要导入views
from flask import Flask, views, session, redirect, url_for
from functools import wraps


app = Flask(__name__)


def auth(func):
    @wraps(func)
    def inner(*args, **kwargs):
        if not session.get("userinfo"):
            return "你还没登录,滚"
        ret = func(*args, **kwargs)
        return ret
    return inner


class MyView(views.MethodView):
    methods = ["GET", "POST"]
    # 设置decorators相当于给这个CBV的所有请求方法都加了指定的装饰器
    # decorators = [auth, ]

    def get(self):
        return "GET"

    def post(self):
        return "POST"


# 第一个参数:路由
# 第二个参数:视图
# name == endpoint 命名路由
app.add_url_rule("/index", view_func=MyView.as_view(name="index"))


if __name__ == __main__:
    app.run()

 

13、自定义路由的正则匹配

from flask import Flask, url_for
from werkzeug.routing import BaseConverter

app = Flask(__name__)


class RegexConverter(BaseConverter):
    """
    自定义URL匹配正则表达式
    """

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

    def to_python(self, value):
        """
        路由匹配时,匹配成功后传递给视图函数中参数的值
        value默认的类型是str,我们可以设置成我们想要的类型
        :param value:
        :return:
        """
        return int(value)

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


# 新加一个匹配规则regex到flask中
# 原本只有 int string等,现在还多了一个regex
app.url_map.converters[regex] = RegexConverter


@app.route(/index/<regex("\d+"):nid>)
def index(nid):
    print(url_for(index, nid=111))
    print(nid, type(nid))
    return Index


if __name__ == __main__:
    app.run()

 

14、蓝图
1. 作用
为我们提供目录的划分,就是解耦用的。


2. 目录
技术分享图片


3. 实现步骤

1,新建一个项目目录 项目目录下建一个同名的python包
2,在项目目录同级下建manager.py
3, 在包的__init__ 实例化Flask对象
4,在manager.py 导入Flask的实例化对象app  app.run()
5, 在Python包里建立views文件夹
    任何一个文件都都可以生成蓝图对象
    from flask import BluePrint
    # 实例化蓝图对象
    bookBlue = BluePrint("bookBlue", __name__)
    @ bookBlue.route("/")
    def index():
        return "xxx"
6, 把蓝图对象注册到app中
    app.register_blueprint(bookBlue, **options)

 

4. 注意
每个蓝图可以指定自己的模板以及静态文件~

还可以在app中注册蓝图的时候指定路由前缀~~

还可以给蓝图加before_request~~


5. 示例代码

技术分享图片
from flask import Flask
from .views.book import bookBlue
from .views.user import userBlue


# 创建Flask的实例化对象app
def create_app():
    app = Flask(__name__, template_folder=templates)  # 指定templates
    app.register_blueprint(userBlue)  # 把蓝图对象注册到app
    app.register_blueprint(bookBlue, url_prefix=/book)  # 还可以指定路由的前缀
    return app
__init__.py
技术分享图片
from BlueDemo import create_app


# 导入Flask的实例化对象app
app = create_app()

if __name__ == __main__:
    # 启动Flask
    app.run()
manage.py
技术分享图片
from flask import Blueprint, render_template


# 实例化一个蓝图对象
userBlue = Blueprint(userBlue, __name__)


@userBlue.route(/user)
def user():
    return render_template(user.html)
views/user.py
技术分享图片
from flask import Blueprint


# 实例化一个蓝图对象
bookBlue = Blueprint(bookBlue, __name__)


# bookBlue蓝图对象,注册到app的时候,指定了url_prefix,相当于做了路由的分发
# 这个视图的路由:/book/list
@bookBlue.route(/list)
def list():
    return "Book_list"


# 这个视图的路由:/book/create
@bookBlue.route(/create)
def create():
    return "Book_create"
views/book.py

 

Flask初识

标签:gconf   实现   hide   file   float   request请求   注册   注意   下载   

原文地址:https://www.cnblogs.com/Zzbj/p/10193810.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!