博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask
阅读量:6994 次
发布时间:2019-06-27

本文共 14425 字,大约阅读时间需要 48 分钟。

一、基本使用

安装:

pip3 install flask

基本使用:

from flask import Flask, request, render_template, redirect, sessionapp = Flask(__name__, template_folder="templates", static_folder="static")app.secret_key = "abc"@app.route("/login", methods=["GET", "POST"])def login():    if request.method == "GET":        return render_template("login.html")    username = request.form.get("username")  # 如果是get请求 request.args    password = request.form.get("password")    if username == "pd" and password == "123":        session["user"] = username        return redirect("/index")    # return render_template("login.html", error="用户名或密码错误")    return render_template("login.html", **{
"error": "用户名或密码错误"})@app.route("/index")def index(): user = session.get("user") if not user: return redirect("/login") return render_template("index.html")if __name__ == "__main__": app.run()

二、配置文件

flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:    {        'DEBUG':                                False,  # 是否开启Debug模式        'TESTING':                              False,  # 是否开启测试模式        'PROPAGATE_EXCEPTIONS':                 None,                                  'PRESERVE_CONTEXT_ON_EXCEPTION':        None,        'SECRET_KEY':                           None,        'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),  # session超时时间        '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,    }
View Code

配置方式1:

app.config["DEBUG"] = True# 由于Config对象本质上是字典,所以还可以使用app.config.update({
"DEBUG": "True"})

配置方式2:

新建一个 settings.py 文件,例如:

# settings.pyclass Config(object):    DEBUG = False    TESTING = False    DATABASE_URI = 'sqlite://:memory:'class ProductionConfig(Config):    DATABASE_URI = 'mysql://user@localhost/foo'class DevelopmentConfig(Config):    DEBUG = Trueclass TestingConfig(Config):    TESTING = True

再使用:app.config.from_object("配置文件类的路径")

所以,生产环境就用生产环境的配置,开发时就用开发环境的配置。

三、路由系统

@app.route("/index", endpoint="xx")  #  endpoint相当于别名def index():    print(url_for("xx"))  # /index  url_for("xx"),反向生成url,默认url_for("函数名")    return "index"
@app.route("/index/
") # 字符串@app.route("/index/
")@app.route("/index/
")@app.route("/index/
")@app.route("/login", methods=["GET", "POST"])# 示例:@app.route("/index/
")def index(user): return user# 常用路由系统有以上五种,所有的路由系统都是基于以下对应关系来处理:DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter,}

反向生成带参数的URL,怎么做呢?

@app.route("/index/
")def index(id): print(url_for("index", id=id)) # id=1 生成固定参数的url return "index"

CBV

from flask import Flask, views, url_forapp = Flask(__name__)def auth(func):    @wraps(func)    def inner(*args, **kwargs):        print('before')        result = func(*args, **kwargs)        print('after')        return resultreturn innerclass IndexView(views.View):    methods = ['GET']    decorators = [auth, ]    def dispatch_request(self):        print('Index')        return 'Index'app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint# 或class IndexView(views.MethodView):    methods = ['GET']    decorators = [auth, ]    def get(self):        return 'Index.GET'    def post(self):        return 'Index.POST'app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint
View Code

@app.route和app.add_url_rule参数

rule                    # URL规则view_func               # 视图函数名称defaults=None           # 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数endpoint=None           # 名称,用于反向生成URL,即: url_for('名称')methods=None            # 允许的请求方式,如:["GET", "POST"]strict_slashes=None     # 对URL最后的 / 符号是否严格要求,                        # 如:                        @app.route('/index',strict_slashes=False),                            访问 http://www.xx.com/index/ 或 http://www.xx.com/index 均可                        @app.route('/index',strict_slashes=True)                            仅访问 http://www.xx.com/indexredirect_to=None,       # 重定向到指定地址                        # 如:                        @app.route('/index/
', redirect_to='/home/
') 或 def func(adapter, id): return "/home/888" @app.route('/index/
', redirect_to=func)subdomain=None, # 子域名访问 from flask import Flask, views, url_for app = Flask(import_name=__name__) app.config['SERVER_NAME'] = 'wupeiqi.com:5000' @app.route("/", subdomain="admin") def static_index(): """Flask supports static subdomains This is available at static.your-domain.tld""" return "static.your-domain.tld" @app.route("/dynamic", subdomain="
") def username_index(username): """Dynamic subdomains are also supported Try going to user1.your-domain.tld/dynamic""" return username + ".your-domain.tld" if __name__ == '__main__': app.run()
View Code

自定制正则路由匹配

from flask import Flask, url_forfrom werkzeug.routing import BaseConverterapp = Flask(import_name=__name__)class RegexConverter(BaseConverter):    """    自定义URL匹配正则表达式    """    def __init__(self, map, regex):        super(RegexConverter, self).__init__(map)        self.regex = regex    def to_python(self, value):        """        路由匹配时,匹配成功后传递给视图函数中参数的值        :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# 添加到flask中app.url_map.converters["regex"] = RegexConverter@app.route("/index/
")def index(id): return url_for("index", id=id)if __name__ == "__main__": app.run()
View Code

四、请求和响应

from flask import Flaskfrom flask import requestfrom flask import render_templatefrom flask import redirectfrom flask import make_responsefrom flask import jsonifyimport osapp = Flask(__name__)BASE_DIR = os.path.dirname(os.path.abspath(__file__))@app.route("/login", methods=["GET", "POST"])def login():    # 请求相关信息    request.method    request.args    request.form    request.values    request.cookies    request.headers    request.path    request.full_path    request.script_root    request.url    request.base_url    request.url_root    request.host_url    request.host    request.files    obj = request.files.get("the_file_name")  # 拿到上传的文件名    obj.save(os.path.join(BASE_DIR, "files", obj.filename))  # 保存到本地路径    # 响应相关信息(响应体)    return "字符串"    data = {
"key": "val"} return jsonify(data) # 相当于 json.dumps(data) return render_template("login.html", **{}) return redirect("/index") # 设置响应头 response = make_response(render_template("index.html")) # 将响应内容封装到这个对象中,再设置 # response是flask.wrappers.Response类型 response.delete_cookie("key") response.set_cookie("key", "val") response.headers["key"] = "val" return responseif __name__ == "__main__": app.run()
View Code

五、Session

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

设置:session["user"] = "xx"获取:session.get("user")    session["user"]删除:session.pop("user", None)# 可以在settings中设置秘钥class DevelopmentConfig(Config):    DEBUG = True    SECRET_KEY = "asdf"

当请求刚到来:flask读取cookie中session对应的值,将该值解密并反序列化成字典,放入内存以便视图函数使用。

当请求结束时:flask会读取内存中字典的值,进行序列化、加密,写入到用户cookie中。

第三方session

"""pip3 install redispip3 install flask-session"""import redisfrom flask import Flask, sessionfrom flask_session import Session# from flask.ext.session import Session  # 老版本,同 from flask_session import Sessionapp = Flask(__name__)app.config["SESSION_TYPE"] = "redis"app.config["SESSION_REDIS"] = redis.Redis(host="127.0.0.1",port=6379)Session(app)@app.route("/login")def login():    session["user"] = "username"    return "login"@app.route("/index")def index():    print(session.get("user"))    return "index"if __name__ == "__main__":    app.run()
View Code

flash

临时存储数据,取了就没了;在session中存储一个数据,读取时通过pop将数据移除。

from flask import Flask, flash, get_flashed_messagesapp = Flask(__name__)@app.route('/test1')def test1():    flash('aa', 'error')  # 第二个参数:分类    flash('bb', 'error')    flash('cc', 'info')    return "Set Session"@app.route('/test2')def test2():    print(get_flashed_messages(category_filter=['error']))  # ['aaaaa', 'bbbbb']    return "Get Session"if __name__ == "__main__":    app.run()
View Code

六、模板

1、Flask 使用的是 Jinja2 模板,所以其语法和 Django 无差别。

{% for k,v in data.items() %}    {
{ k }} {
{ v.name }} {
{ v["age"] }} {
{ v.get("hobby", "默认") }}{% endfor %}
@app.route("/test")def test():    txt1 = Markup("

哈哈

") # Markup相当于Django的mark_safe txt2 = "

呵呵

" return render_template("test.html", **{
"txt1": txt1, "txt2": txt2})#######################################################################{
{ txt1 }}{
{ txt2|safe }}
@app.template_global()def func1(a1, a2):    return a1+a2@app.template_filter()def func2(a1, a2, a3):    return a1+a2+a3# 调用方式,模板中:{
{ func1(1,2) }} {
{ 1|func2(2,3) }}

2、自定义模板方法

from flask import Flask, render_templateapp = Flask(__name__)def func():    return '

哈哈哈

'@app.route('/test')def test(): return render_template('test.html', xx=func)if __name__ == "__main__": app.run()################################################
Title

自定义函数

{
{ xx()|safe }}
View Code

macro

    
Title{# 定义 #}{% macro func(name, type='text', value='') %} {% endmacro %}{# 执行 #}{
{ func('password', type='password', value=123456) }}
View Code

七、特殊装饰器

from flask import Flaskapp = Flask(__name__)@app.before_first_requestdef before_first_request1():    print('before_first_request1')@app.before_first_requestdef before_first_request2():    print('before_first_request2')@app.before_requestdef before_request1():    print('before_request1')@app.before_requestdef before_request2():    print('before_request2')@app.after_requestdef after_request1(response):    print('after_request1', response)    return response@app.after_requestdef after_request2(response):    print('after_request2', response)    return response@app.route('/')def index():    return 'index'if __name__ == '__main__':    app.run()# before_first_request1# before_first_request2# before_request1# before_request2# after_request2 
# after_request1
############################################# 比较少的函数中需要额外添加功能,使用装饰器def auth(func): @functools.wraps(func) def inner(*args, **kwargs): if not session.get('user'): return redirect(url_for('login')) ret = func(*args, **kwargs) return ret return inner@app.route('/index')@authdef index(): return 'index' # 给全局加上登录验证@app.before_requestdef before_request(): if request.path == "/login": return None if session.get("user"): return None return redirect("login")############################################@app.errorhandler(404)def page_not_found(error): return '页面不见了'
View Code

八、蓝图

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

小中型:

account.py

from flask import Blueprintfrom flask import render_templateaccount = Blueprint("account", __name__)@account.route("/login", methods=["GET", "POST"])def login():    return render_template("login.html")

course.py

from flask import Blueprintcourse = Blueprint("course", __name__)

__init__.py

from flask import Flaskfrom .views.account import accountfrom .views.course import courseapp = Flask(__name__, template_folder="templates", static_folder="statics", static_url_path="/static")app.register_blueprint(account)app.register_blueprint(course)

run.py

from pro_flask import appif __name__ == "__main__":    app.run()

大型:

admin / __init__.py

from flask import Blueprintadmin = Blueprint(    "admin",    __name__,    template_folder="templates",    static_folder="static")from . import views

admin / views.py

from . import admin@admin.route("/index")def index():    return "Admin.Index"

blog / __init__.py

from flask import Blueprintblog = Blueprint(    "blog",    __name__,    template_folder="templates",    static_folder="static")from . import view

blog / views.py

from . import blog@blog.route("/index")def index():    return "Blog.Index"

pro_flask / __init__.py

from flask import Flaskfrom .admin import adminfrom .blog import blogapp = Flask(__name__)app.debug = Trueapp.register_blueprint(admin, url_prefix="/api")  # url前缀app.register_blueprint(blog)

run.py

from pro_flask import appif __name__ == "__main__":    app.run()

url_prefix参数的作用:

http://127.0.0.1:5000/index      # Blog.Indexhttp://127.0.0.1:5000/api/index  # Admin.Index

小中型应用程序目录:

大型应用程序目录:

九、Flask插件

转载于:https://www.cnblogs.com/believepd/p/10295168.html

你可能感兴趣的文章
上班这点事
查看>>
90 [LeetCode] Subsets2
查看>>
php的spl_autoload_register函数的一点个人见解
查看>>
halcon算子翻译——get_framegrabber_param
查看>>
Codeforces 892B Wrath(模拟)
查看>>
Scala中Infix Type实战详解之Scala学习笔记-45
查看>>
使用Python2.7在windows系统中os.mknod调用错误
查看>>
{4,4,8}倒还好,不过{4,8}就会有问题了。这里倒是一个bug。一个可用的办法就是用一个vis......
查看>>
[LeetCode] Clone Graph, Solution
查看>>
const 类型的指针
查看>>
HTTP返回值
查看>>
Float Labeled EditText
查看>>
删除SQL日志语句,经测试8G日志文件都可以删除
查看>>
Self referencing loop in Json.Net JsonSerializer from custom JsonConverter (Web API)
查看>>
chkconfig命令 centos 开机启动命令
查看>>
《解释的工具:生活中的经济学原理》读书笔记3
查看>>
enumerate遍历列表
查看>>
Maximum Depth of Binary Tree
查看>>
使用NSURLProtocol实现UIWebView的离线缓存(转)
查看>>
UVA 11491 Erasing and Winning
查看>>