Flask的使用02

flask基础

1.Flask 启动:

form flask import Flask
app = Flask(name)
@app.route("/")
def index():
	return "Hello"

app.run("0.0.0.0",9527,debug=True)

2.路由
methods = [“GET”,“POST”,“PUT”,“DELETE”]

3.Response:
5个返回类型
1.字符串 HttpResponse
2.模板页面 render render_template - templates
3.重定向 redirect redirect("/login")
Flask特殊值 小儿子
4.打开并返回文件内容 send_file(“文件的路径”)
5.标准JSON格式的Response jsonify({name:1}) # Content-type:application/json

4.Request:

from flask import request
method 	获取当前请求的 请求方式
url	   	完整访问路径 包含url参数
path	路由地址

form	获取FormData中的数据
	1.to_dict
	2.get()
args	获取url中的参数数据
	1.to_dict
	2.get()

values 	深坑 通常用于查看args formData中数据 (如果formData中的key与args中的key重名,则被args的参值覆盖掉)
json 请求头中 Content-type:application/json 数据存放在 request.json
data 请求头中的Content-type不被认可 会将原始的请求体中的数据 存放成b"" Content-type:application/json 也会保存原始请求体信息

5.Jinja2
{{}} 取值 执行
{%%} 逻辑代码 if else for

6.session
from flask import session

app.secret_key = "!@#$%^&*())(*&^%$#"

session["user"] = "value"
	
将序列化后的session字符串儿存放在客户端的cookies中

路由配置 + 路由详情

路由配置:app.add_url_rule(“路由地址”,view_func=视图函数,endpoint=“反向地址”)
methods 允许进入当前视图函数的请求方式
endpoint url_for 反向生成URL地址 默认是视图函数名 -解决视图函数重名
defaults 传递默认参数 defaults={“nid”:1} def index(nid)
strict_slashes 是否严格遵守URL地址规则 == True 在地址末尾不可以出现 / 反之可以
redirect_to 永久重定向 “/index” http - 301
subdomain 子域名配置 必须和 app中的 SERVER_NAME 联动

app.add_url_rule

from flask import Flask, render_template, request,url_for
app = Flask(__name__)
@app.route("/")
def index():
    return "这是主页"
def login():
    print(url_for("login"))#/login
    return "这是登录"
app.add_url_rule("/login",view_func=login)
app.run()

rule(第一个指的是路由匹配规则), endpoint=None, view_func=None,

url_for方向解析到真实的路由

from flask import Flask, redirect, url_for
app = Flask(__name__)

@app.route('/')
def index():
    login_url = url_for('login')
    return redirect(login_url)
    return u'这是首页'

@app.route('/login/')
def login():
    return u'这是登陆页面'

@app.route('/question/<is_login>/')
def question(is_login):
    if is_login == '1':
        return u'这是发布问答的页面'
    else:
        return redirect(url_for('login'))
if __name__ == '__main__':
    app.run(debug=True)

参数的意义

endpoint相当于django中的反向的解析名字

defaults={“nid”:1} 传默认参数

view_func指的是路由对应的视图函数

strict_slashes=False 严格模式不能带末尾的斜杠 默认是True

redirect_to="/login" 直接重定向到登录视图(永久重定向)http -301

举例

@app.route('/greeting/<name>')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

注意,add_url_rule函数实现了同样的目的,只不过没有使用装饰器,因此,下面的程序是等价的:

# 抬头没有使用路由装饰器,我们在最后用另一种方法添加路由.
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

app.add_url_rule('/greeting/<name>', 'give_greeting', give_greeting)

动态路由

@app.route("/get/<filename>") # 动态路由参数
def get_file(filename):
    import os
    path = os.path.join("image",filename)#当前目录下的image
    return send_file(path)

@app.route("/index/<name>")
def index(name):
    return "这是主页 "+str(name)

flask_restx官方文档 flask reload_json

@app.route("/test",defaults={"nid":1})
def test(nid):
    return "这是测试页面 "+str(nid)

flask_restx官方文档 flask reload_flask_02


访问路径 http://127.0.0.1:5000/test 严格模式不能带末尾的斜杠

@app.route("/test",defaults={"nid":1},strict_slashes=False)
def test(nid):
    return "这是测试页面 "+str(nid)

访问路径 http://127.0.0.1:5000/test    都可以

http://127.0.0.1:5000/test/

flask_restx官方文档 flask reload_flask_restx官方文档_03

Flask实例化配置

template_folder="template"		更改模板存放目录
static_folder="statics"			更改静态文件存放目录
static_url_path="/s"			更改静态文件访问路径 默认- /static_folder    ==>在浏览器上的地址为/s

app=Flask(__name__,template_folder="template",static_folder="statics",static_url_path="/s")

真实文件存放路径

flask_restx官方文档 flask reload_flask_04

静态文件的访问路径http://127.0.0.1:5000/s/1.png

flask_restx官方文档 flask reload_flask_05

flask中config配置管理问题

app对象配置

#默认配置
 default_config = ImmutableDict({
        'ENV':                                  None,
        'DEBUG':                                None,
        'TESTING':                              False,
        'PROPAGATE_EXCEPTIONS':                 None,
        'PRESERVE_CONTEXT_ON_EXCEPTION':        None,
        'SECRET_KEY':                           None,
        'PERMANENT_SESSION_LIFETIME':           timedelta(days=31),
        'USE_X_SENDFILE':                       False,
        'SERVER_NAME':                          None,
        'APPLICATION_ROOT':                     '/',
        'SESSION_COOKIE_NAME':                  'session',
        'SESSION_COOKIE_DOMAIN':                None,
        'SESSION_COOKIE_PATH':                  None,
        'SESSION_COOKIE_HTTPONLY':              True,
        'SESSION_COOKIE_SECURE':                False,
        'SESSION_COOKIE_SAMESITE':              None,
        'SESSION_REFRESH_EACH_REQUEST':         True,
        'MAX_CONTENT_LENGTH':                   None,
        'SEND_FILE_MAX_AGE_DEFAULT':            timedelta(hours=12),
        'TRAP_BAD_REQUEST_ERRORS':              None,
        'TRAP_HTTP_EXCEPTIONS':                 False,
        'EXPLAIN_TEMPLATE_LOADING':             False,
        'PREFERRED_URL_SCHEME':                 'http',
        'JSON_AS_ASCII':                        True,
        'JSON_SORT_KEYS':                       True,
        'JSONIFY_PRETTYPRINT_REGULAR':          False,
        'JSONIFY_MIMETYPE':                     'application/json',
        'TEMPLATES_AUTO_RELOAD':                None,
        'MAX_COOKIE_SIZE': 4093,
    })

在项目中我们需要配置各种环境。
如果我们的配置项很少的话,
可以直接简单粗暴的来;
比如:

app =Flask(name)
app.config[‘DEBUG’]=True

# app.config["SECRET_KEY"] = "#$%^&*()"
# app.config["outher_config"] = "no_error"#往这个字典里加一些奇怪的参数也不会报错,因为没有用到
# app.config["JSONIFY_MIMETYPE"] = "application/json"
# app.config["TESTING"] = True

app.config其实是实例化了flask.config.Config类的实例,
继承于python内置数据结构dict字典,可以使用update方法:

app.config.update(
DEBUG=True,
SECRET_KEY='xxxx'
)

如果设置很多的情况下,想要集中起来管理设置项,
应该将他们存放在一个文件里面。
app.config支持很多的配置方式。
比如现在我们有叫settings.py的配置文件,里面的内容是
sss=yy
我们可以有三种方式加载。
1)使用配置文件进行加载

app.config.from_object('settings.py')#使用模块的名字

当settings.py内容如下时

class MyConfig(object):
    DEBUG=True
    SECRET_KEY = "23456789#$%^&*()"
    SESSION_COOKIE_NAME = "sssss"

class MyConfigTesting(object):
    TESTING = True
    SECRET_KEY = "&&*%^%$&%$#$%^&*()"
    SESSION_COOKIE_NAME = "xianshangdeSession"

使用的时候

from settings import MyConfig,MyConfigTesting
app.config.from_object(MyConfig)
app.config.from_object(MyConfigTesting)
# app.config.from_json("json文件")

也可以在引用之后直接传入对象

import settings
app.config.from_object(settings)

2)使用文件名字加载。直接传入名字就行了
别的后缀的也可以,不局限于.py的

app.config.from_pyfile('settings.py',silent=True)

默认当配置文件不存在的时候抛出异常,

使用silent=True的时候只是会返回False,但是不抛出异常

3)使用环境变量加载。这种方法依然支持silent参数,获得路径后其实
还是使用from_pyfile的方式加载的。

$ export YOURAPPLICATION_SETTINGS='settings.py'

app.config.from_envvar('YOURAPPLICATION_SETTINGS')

特殊装饰器

before_first_request 重启之后访问第一次到达执行的函数,不阻塞

before_request 在请求进入视图函数之前 做出响应
after_requset 在视图函数处理之后 响应返回客户端之前

正常情况:be1 - be2 - be3 - views - af3 - af2 - af1 返回顺序是定义代码时的倒叙
异常情况:be1 - af3 - af2 - af1 异常阻塞请求的情况



@app.errorhandler(404) # 重定义错误提示
def error404(arg):
	print(arg)
	return redirect("https://www.autohome.com.cn/beijing/asdfgasdfasdf")

before_first_request

before_first_request 按注册的顺序 顺序执行

@app.before_first_request
def first():
    print("这是第一次进入配置")
    return None

after_request的写法注意 要传res(形参的名字可变) 按注册的顺序 倒序执行

@app.after_request
def after_request1(res):
    print("进入after_request1")
    return res

示例

from flask import Flask

app=Flask(__name__)

@app.before_first_request
def first():
    print("这是第一次进入配置")
    return None
@app.route("/")
def index():
    print("进入视图页面")
    return "主页"
@app.before_request
def before():
    print("进入before1")
    return None
@app.before_request
def before2():
    print("进入before2")
    return None
@app.before_request
def before3():
    print("进入before3")
    return None
@app.after_request
def after_request1(res):
    print("进入after_request1")
    return res
@app.after_request
def after_request2(res):
    print("进入after_request2")
    return res
@app.after_request
def after_request3(res):
    print("进入after_request3")
    return res
app.run(debug=True)

#结果如下
这是第一次进入配置
进入before1
进入before2
进入before3
127.0.0.1 - - [26/Feb/2018 17:45:21] "GET / HTTP/1.1" 200 -
进入视图页面
进入after_request3
进入after_request2
进入after_request1

优化404页面

后端

@app.errorhandler(404)
def error404(arg):
    print(arg)
    return render_template("404.html")

效果

flask_restx官方文档 flask reload_json_06

创建项目的规范

在项目1下

创建app的python包(之后创建static,templates,views文件夹)

└─app
├─static ==>存放静态文件的
├─templates ==>存放模板文件的
├─views ==>存放视图函

├─init.py        ==>存放初始化项目的函数

└─manager.py ==>管理/启动项目的(与app目录同级)

创建manager.py(与app目录同级)的文件(小技巧,可以用pycharm标记项目文件夹为根 方便写程序)

manager.py

from app import create_app
test_app = create_app()
if __name__ == '__main__':
    test_app.run(host='0.0.0.0',port='5000',debug=True)

app/init.py

from flask import Flask
from .views.user import u_bp

def create_app():
    app = Flask(__name__)

    app.register_blueprint(u_bp)

    return app

app/views/user.py

(1)导入Blueprint

(2)实例化u_bp = Blueprint(“user”,name)对象

(3)开始写正常的视图

from flask import Blueprint

u_bp = Blueprint("user",__name__)

@u_bp.route("/user")
def users():
    return "I am users bp"