flask 路由 php文件,Flask路由层

一:URL简介

1:定义

url是统一资源定位符(Uniform Resource Locator的简写),对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

2:组成

scheme://host:port/path/?parameter=xxx#anchor

https://www.baidu.com/Public/linux/?fr=aladdin#23scheme:代表的是访问的协议,一般为http或者https以及ftp等。

host:主机名,域名,比如www.baidu.com。

port:端口号。当你访问一个网站的时候,浏览器默认使用80端口。

path:路径。比如:www.baidu.com/Public/linux/?python=aladdin#23,www.baidu.com后面的Public/linux就是path。

query-string:查询字符串,比如:www.baidu.com/s?wd=python,?后面的python=aladdin就是查询字符串。

anchor:锚点,后台一般不用管,前端用来做页面定位的。比如:https://www.oldboyedu.com/Public/linux/?fr=aladdin#23 ,#后面的23就是锚点

3:作用

顾名思义统一资源定位符,是用来做定位用的,我们的web开发无非是要调用程序,而调用的具体程序我们称之为python的视图函数,URL建立了与Python视图函数一一对应的映射关系,通俗易懂可以理解为一条命令触发了一个python的函数或类。

二:URL使用方式

1:简介

在Flask程序中使用路由我们称之为注册路由,是使用程序实例提供的app.route()装饰器注册路由,而括号内的字符串就是url,注册路由的过程就是完成了 url和python类或函数映射的过程,可以理解为会有一张表保存了url与python类或函数的对应关系。这样我们以url访问flask就可以找到对应的程序

@app.route('/')defhello_world():return 'Hello World!'

2:url传参方式

2.1:动态传参

例如,你想根据学生的id找到具体的学生,http://127.0.0.1:5000/student_list// 仍然在path部分 ,但是你没必要写多个路由,我们Flask支持这种可变的路由。

@app.route('/student_list//')defstudent_list(student_id):return '学生{}号的信息'.format(student_id)

2.2:动态路由过滤

可以对参数限定数据类型,比如上面的文章详情,限定student_id必须为整数类型

@app.route('/student_list//')defarticle_detail(student_id):return '学生{}号的信息'.format(student_id)

主要有这几种类型过滤:

string: 默认的数据类型,接收没有任何斜杠"  /"的字符串

int: 整型

float: 浮点型

path: 和string类型相似,但是接受斜杠,如:可以接受参数/aa/bb/cc/多条放在一起

uuid: 只接受uuid格式的字符串字符串,

3: url_for()的使用:

3.1简介视图函数:

我们在访问一个网址的时候在调用flask项目的时候需要调用的是一段具体的代码,也就是一个python类或者python函数,在这里这个python类我们称之为视图类,python函数我们称之为视图函数。

3.2 url_for()的作用:

如果我们在视图函数中想使用一个url,比如给前端返回,或者我们在这个视图函数中返回一个模板文件都会使用到url,url相当于一把钥匙可以开启一些资源。如果你修改了注册路由编写的url规则,相当于修改了钥匙。那么其他的视图函数依旧是使用了原来的钥匙就无效了,如果项目是一个大项目,你一点点手动的去改涉及到的的url就不合理了。url_for()就是用来解决这个问题的。

3.3url_for()的原理:

利用视图函数名字一般不会改变的特性,利用视图函数的名字去动态精准的获取url,以便于开发使用。

url_for('视图函数名字') #输出该视图函数url

from flask importFlask,url_for

app= Flask(__name__)

app.config.update(DEBUG=True)

@app.route('/',endpoint="sb")defindex():

real_url=url_for("sb")returnreal_urlif __name__ == '__main__':

app.run()

四:路由源码分析

from flask importFlask

app= Flask(__name__)

@app.route('/')defhello_world():return 'Hello World!'

if __name__ == '__main__':

app.run()

1:第一步

2:第二步

3:第三步

4:第四步

PS:

(1)此处装饰器参数f 即为上述被装饰的函数

(2)灵魂代码为:self.add_url_rule(rule, endpoint, f, **options)

self.add_url_rule(rule, endpoint, f, **options)

'''self 当前flask产生的对象 app

endpoint:函数别名

f:当前被装饰的函数'''

5:第五步

PS;

1:首先判断是否有别名 如果没有别名走该_endpoint_from_view_func方法

2:如果有别名使用自己的传入的别名

3:判断是否传入请求方式 如果没有传入请求方式 默认使用get方式

4:别名不能重复

4.1:

1:首先假设没有传入别名 即old_func为空 条件不成立

2:条件不成立 别名为当前函数名 此时别名不为空了

3:再次调用的时候 别名会有值 如果不和函数名相同 直接异常

4:如果别名相同 那么当调用函数的时候 有多个函数别名相同 该调用哪个函数

六:CBV

1:基本使用方式

from flask importFlask, views

app= Flask(__name__)

app.debug=TrueclassIndexView(views.View):defdispatch_request(self):print('Index')return 'Index!'

app.add_url_rule('/index', view_func= IndexView.as_view(name='index'))

2:问题探讨

(1)为什么as_view()括号内加上name

(2)为什么执行dispatch_request 而不是像django GET,POST等

3:源码分析

(1)走父类的as_view方法

@classmethoddef as_view(cls, name, *class_args, **class_kwargs):''':param cls:

:param name: 从代码中可以看到 name这个参数必须传递

:param class_args:

:param class_kwargs:

:return:

部分代码展示'''

def view(*args, **kwargs):

self= view.view_class(*class_args, **class_kwargs)return self.dispatch_request(*args, **kwargs)#view 上述view函数view.view_class= cls #view_class 绑定当前类

view.__name__ = name #将函数名称 更改为传过来的名称

return view #返回当前函数

PS:

1:假设上述不传递name这个参数 上述路由可以更改为

app.add_url_rule('/index', view_func=view)

2:从上述更改的路由可以看到 所有的路由都指向一个view函数

3:代码分析add_url_rule

if view_func is notNone:

old_func=self.view_functions.get(endpoint)if old_func is not None and old_func !=view_func:raiseAssertionError("View function mapping is overwriting an"

"existing endpoint function: %s" %endpoint

)

self.view_functions[endpoint]= view_func #根路由

PS:

(1)如果不传递name

(2)首先获取不到别名 别名默认为函数名

(3)当再次访问的时候 如果函数名不等于别名 则会直接抛出异常

def view(*args, **kwargs):

self= view.view_class(*class_args, **class_kwargs)return self.dispatch_request(*args, **kwargs)

1:上述self 为当前类名称

2:在类中可以调用dispatch_request方法

七:CBV改良模式

1:改良

classIndexView(views.MethodView):

methods=["GET","POST"]defget(self):print('Index')return 'Index!,get'

defpost(self):return 'Index!,post'

2:源码分析

def dispatch_request(self, *args, **kwargs):

meth=getattr(self, request.method.lower(), None)

if meth is None and request.method == "HEAD":

meth= getattr(self, "get", None)assert meth is not None, "Unimplemented method %r" %request.methodreturn meth(*args, **kwargs)

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值