Flask框架【三】—路由和视图
一、Flask路由系统
1.动态参数路由
路由的写法,以及获取路由中传递的参数
@app.route('/user/<username>') # 常用的,不加参数的时候默认是字符串形式的 @app.route('/post/<int:post_id>') # 常用的,指定int,说明是整型的 @app.route('/post/<float:post_id>') @app.route('/post/<path:path>') @app.route('/login', methods=['GET', 'POST'])
路由系统有以上五种,所有的路由系统都是基于以下对应关系来处理
DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter, }
2.反向生成URL:url_for
endpoint("name") # 别名,相当于django中的name
反向解析需要导入
from flask import Flask, url_for
使用例子
@app.route('/index',endpoint="xxx") # endpoint是别名 def index(): v = url_for("xxx") print(v) return "index" @app.route('/zzz/<int:nid>',endpoint="aaa") # endpoint是别名 def zzz(nid): v = url_for("aaa",nid=nid) print(v) return "index2"
3.路由参数详解
在flask框架中,路由的指定方式有两种:
- app.route()中填写路由
- app.add_url_rule()中填写路由
方式一: @app.route('/index',endpoint='index') 方式二: app.add_url_rule('/index',index)
@app.route和app.add_url_rule的参数:
-
rule, URL规则
-
view_func, 视图函数名称
-
defaults=None,默认值,当URL中无参数,函数需要参数时,使用
from flask import url_for @app.route("/info", methods=["GET", "POST"], endpoint="r_info", defaults={"nid": 100}) def student_info(nid): print(url_for("r_info")) # /info # stu_id = int(request.args["id"]) print(nid) # 100 return f"Hello Old boy {nid}" # Python3.6的新特性 f"{变量名}"
-
defaults={'k':'v'};为函数提供参数,一旦有的话,视图函数中必须有一个形参去接受,并且要与参数的键名字一致,不然会报错
-
endpoint=None,名称,用于反向生成URL,即: url_for('名称')
endpoint用于路由和视图函数的映射,相当于是在django的别名,可以用于视图函数的反向解析。
from flask import url_for @app.route("/info", methods=["GET", "POST"], endpoint="r_info") def student_info(): print(url_for("r_info")) # /info stu_id = int(request.args["id"]) return f"Hello Old boy {stu_id}" # Python3.6的新特性 f"{变量名}"
-
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/index
-
redirect_to=None, 重定向到指定地址,永久重定向
@app.route('/index/<int:nid>', redirect_to='/home/<nid>') 或 def func(adapter, nid): return "/home/888" @app.route('/index/<int:nid>', redirect_to=func)
-
subdomain=None,子域名访问
app.config["SERVER_NAME"] = "oldboy.com" @app.route("/info",subdomain="DragonFire") def student_info(): return "Hello Old boy info" # 访问地址为: DragonFire.oldboy.com/info
扩展Flask的路由系统,让他支持正则,这个类必须这样写,继承BaseConverter
from flask import Flask,url_for app = Flask(__name__) # 定义转换的类 from werkzeug.routing import BaseConverter 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 # 添加到converts中 app.url_map.converters['regex'] = RegexConverter # 进行使用 @app.route('/index/<regex("\d+"):nid>',endpoint='xx') def index(nid): url_for('xx',nid=123) # 反向生成,就会去执行to_url方法 return "Index" if __name__ == '__main__': app.run()
二、视图函数
1.django中的CBV模式
CBV模式就是使用面向对象来实现函数的封装,
urls.py
url(r"^login/", views.Login.as_view()), # 使用as_view
views.py
from djangp.views import Views class Login(View): def get(self,request): return render(request,"login.html") def post(self,request): return HttpResponse("...")
2.Flask中的FBV模式
方式一
@app.route('/index',endpoint='index') def index(nid): url_for('index',nid=123) return "首页"
方式二
def index(nid): url_for('index',nid=123) return "首页" app.add_url_rule('/index',index)
3.Flask中的CBV模式
flask中的CBV,也就是视图类的写法来实现视图处理逻辑。
from flask import Flask, views, url_for app = Flask(__name__) def auth(func): # 定义装饰器函数 def inner(*args, **kwargs): result = func(*args, **kwargs) return result return inner class IndexView(views.MethodView): # methods = ['POST'] #只允许POST请求访问 decorators = [auth, ] # 如果想给所有的get,post请求加装饰器,就可以这样来写,也可以单个指定 def get(self): # 如果是get请求需要执行的代码 v = url_for('index') print(v) return "GET" def post(self): # 如果是post请求执行的代码 return "POST" app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) # name指定的是别名,会当做endpoint使用 if __name__ == '__main__': app.run()
衣带渐宽终不悔,为伊消得人憔悴!