Flask 第二话之路由及返回Response

一、自带路由转接器

DEFAULT_CONVERTERS = {
  'default': UnicodeConverter,
  'string': UnicodeConverter,
  'any': AnyConverter,
  'path': PathConverter,
  'int': IntegerConverter,
  'float': FloatConverter,
  'uuid': UUIDConverter,
}

二、URL路径

1、int

# http://127.0.0.1:5000/a/1 => 第1页
@app.route('/a/<int:aid>')
def aaa(aid):
    return '第{}页'.format(aid)

2、string

# http://127.0.0.1:5000/a/1/xiaoming => xiaoming第1页
@app.route('/a/<int:aid>/<string:sss>')
def bbb(aid,sss):
    return '{}第{}页'.format(sss,aid)

3、path

# http://127.0.0.1:5000/a/args1/args2/sss/ => 路径:args1/args2
@app.route('/a/<path:text>/sss/')
def ccc(text):
    return '路径:{}'.format(text)

4、any

# http://127.0.0.1:5000/user/1 => 用户详情:1
# 或者
# http://127.0.0.1:5000/blog/1 => 博客详情:1
@app.route('/<any(blog,user):url_path>/<id>')
def ddd(url_path,id):
    if url_path == 'blog':
        return '博客详情:{}'.format(id)
    else:
        return '用户详情:{}'.format(id)

5、?args1=''&args2=''

# http://127.0.0.1:5000/b/?wss=wwww => 参数:wwww
@app.route('/b/')
def eee():
    ws = request.args.get('wss')
    return '参数:{}'.format(ws)

 三、自定义正则路由

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

app = 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/<regex("\d+"):nid>')
def index(nid):
  print(url_for('index', nid='888'))
  return 'Index'


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

 四、@app.route() 装饰器中的参数

@app.route("/info", methods=["GET", "POST"])

 # methods : 当前 url 地址,允许访问的请求方式

 # GET:获取资源,GET操作应该是幂等性的

 # HEAD:想要获取信息,但是只关心消息头。应用应该像处理GET请求一样来处理它,但是不返回实际内容

 # POST:创建一个新的资源

 # PUT:完整地替换资源或者创建资源。PUT操作虽然有副作用,但也应该是幂等性的。

 # DELETE:删除资源。DELETE操作有副作用,但是也是幂等性的。

 # OPTIONS:获取资源支持的所用HTTP方法。

 # PATCH:局部更新,修改某个已有的资源。

endpoint : 反向url地址,默认为视图函数名 (url_for)

# http://127.0.0.1:5000/list/ => /add/
@app.route('/list/',endpoint='mss')
def ms():
    return url_for("ad")

@app.route('/add/',endpoint='ad')
def ad():
    return 'ad'

defaults : 视图函数的参数默认值 defaults = {"num1":100}

# http://127.0.0.1:5000/add => 100
@app.route('/add',defaults={"num1": 100})
def ad(num1):
    return str(num1)

strict_slashes : url地址结尾符"/"的控制 False : 无论结尾 "/" 是否存在均可以访问 , True : 结尾必须不能是 "/"

# 访问地址 : /info
@app.route("/info", strict_slashes=True)
def student_info():
    url_for('student_info')
    return "info"

# 访问地址 : /infos  or  /infos/
@app.route("/infos", strict_slashes=False)
def student_infos():
    url_for('student_infos')
    return "infos"

redirect_to : url地址重定向

# http://127.0.0.1:5000/info/ => http://127.0.0.1:5000/infos/
@app.route("/info/",redirect_to="/infos")
def student_info():
    return "info"

@app.route("/infos/")
def student_infos():
    return "infos"

subdomain : 子域名前缀 subdomian="DragonFire" 这样写可以得到 DragonFire.oldboyedu.com 前提是app.config["SERVER_NAME"] = "oldboyedu.com"

app.config["SERVER_NAME"] = "dooc.com"

@app.route("/info",subdomain="abc")
def b_info():
    return "二级域名跳转"

# 访问地址为:  abc.dooc.com/info

 五、flask的Response

  1. 如果返回的是一个字符串,那么flask会重新创建一个werkzeug,wrappers,Response对象,Response将该字符串作为主体,状态码为200,MIME的类型为text/html,然后返回该Response对象。
  2. 如果返回的是一个元组,元组的数据类型是(response, status, headers).
    status的值会覆盖默认的200状态码,headers可以是一个列表和字典,作为额外的消息头。
  3. 可以返回’Response‘及其子类。

1、自定义字典类型的返回方法:

from flask import Flask,url_for,Response,jsonify

# 字典类型自定义返回
# 1、继承Response对象
class JSONResponse(Response):
     # 2、定义一个和父类相同的force_type类函数
     @classmethod
     def force_type(cls, response, environ=None):
         """
         :param response:
         :param environ:
         :return:
         """
         print(response)
         # 字典类型转换为json类型并且是response对象
         if isinstance(response,dict):
             response = jsonify(response)

         # 返回继承父类Response的force_type方法的返回值
         return super(JSONResponse,cls).force_type(response,environ)

# 3、修改response_class的对象
app.response_class = JSONResponse

1.1字符串返回

@app.route('/')
def home():
    return 'hello'

1.2设置cookie返回

# http://127.0.0.1:5000/list1/ => Request Headers >>> Set-Cookie: aaa=111; Path=/
@app.route('/list1/')
def list1():
    res = Response('hello')
    res.set_cookie('aaa','111')
    return res

1.3元组返回:元组返回时第三个字典类型的参数将返回到请求头中

# http://127.0.0.1:5000/list2/ => Request Headers >>> aaa: 111
@app.route('/list2/')
def list2():

    return 'list2',200,{'aaa':'111'}

1.4字典返回:使用了上方的自定义返回类

# http://127.0.0.1:5000/list3/ => {'name':'lixingxing','age':18}
@app.route('/list3/')
def list3():
    return {'name':'lixingxing','age':18}

 

posted @ 2020-02-17 12:10  我在地球凑人数的日子  阅读(505)  评论(0)    收藏  举报