今天是在尚学堂学习python第52天今天学习了url_for使用,自定义URL转换器,页面跳转和重定向,视图函数Response返回值详解
url_for使用详解
一般我们通过一个 URL 就可以执行到某一个函数。如果反过来,我们知道一个函数,怎么去获得
这个 URL 呢? url_for 函数就可以帮我们实现这个功能。
url_for() :函数接收两个及以上的参数,他接收函数名作为第一个参数,接收对应URL规则的命名参数,如果还出现其他的参数,则会添加到 URL 的后面作为查询参数。
如:
@app.route('/post/list/<page>/')
def my_list(page):
return 'my list'
@app.route('/')
def hello_world():
# 构建出来的url:/post/my_list/2?num=8
return url_for('my_list',page=2,num=8)
# return "/post/list/2?num=8"
为什么选择`url_for` 而不选择直接在代码中拼 URL 的原因有两点:
1. 将来如果修改了 URL ,但没有修改该 URL 对应的函数名,就不用到处去替换 URL 了。
2. url_for() 函数会转义一些特殊字符和 unicode 字符串,这些事情 url_for 会自动的帮我们
搞定。
如:
@app.route('/login/')
def login():
return 'login'
@app.route('/')
def hello_world():
return url_for('login', next='/')
# /login/?next=/
# 会自动的将/编码,不需要手动去处理。
# url=/login/?next=%2F
自定义URL转换器
自定义URL转换器的步骤:
转换器是一个类,且必须继承自werkzeug.routing.BaseConverter。
1. 实现一个类,继承自`BaseConverter`。
2. 在自定义的类中,重写`regex`,也就是这个变量的正则表达式。
3. 将自定义的类,映射到`app.url_map.converters`上。理解为加入字典DEFAULT_CONVERTERS中
比如:
app.url_map.converters['tel']=TelephoneConveter
注意:to_python方法和to_url方法的作用
1.在转换器类中,实现to_python(self,value)方法,这个方法的返回值,将会传递到 view函数中作为参数。
2.在转换器类中,实现to_url(self,values)方法,这个方法的返回值,将会在调用url_for函数的时候生成符合要求的URL形式。
页面跳转和重定向
重定向分为永久性重定向和暂时性重定向,在页面上体现的操作就是浏览器会从一个页面自动跳转到另外一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应
该给他重定向到登录页面。
永久性重定向: http 的状态码是 301 ,多用于旧网址被废弃了要转到一个新的网址确保用
户的访问,最经典的就是京东网站,你输入 http://www.jingdong.com 的时候,会被重定向
到 http://www.jd.com ,因为 http://jingdong.com 这个网址已经被废弃了,被改成 http://jd.com ,所以这种情况
下应该用永久重定向。
暂时性重定向:http 的状态码是 302 ,表示页面的暂时性跳转。比如访问一个需要权限的
网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
用淘宝网演示为例进行讲解。
flask中重定向:重定向是通过 redirect(location,code=302) 这个函数来实现的, location 表示需要重定向到的 URL ,应该配合之前讲的 url_for() 函数来使用, code 表示采用哪个重定向,默认是 302 也即 暂时性重定向 ,可以修改成 301 来实现永久性重定向。
例如:
from flask import Flask,request,url_for,redirect
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/login/')
def login():
return '这是登录页面'
#falsk中重定向
@app.route('/profile/')
def proflie():
if request.args.get('name'):
return '个人中心页面'
else:
# return redirect(url_for('login'))
return redirect(url_for('login'),code=302)
if __name__ == '__main__':
app.run(debug=True)
视图函数Response返回值详解
关于响应(Response)
视图函数中可以返回以下类型的值:
1.Response 对象及其子类对象
2.字符串。其实 Flask 是根据返回的字符串类型,重新创建一个 werkzeug.wrappers.Response 对象, Response 将该字符串作为主体,状态码为200, MIME 类型为 text/html ,然后返回该 Response 对象
3.元组。元组中格式是 (response,status,headers) 。 response 为一个字符串, status 值是
状态码, headers 是一些响应头。即(响应体,状态码,头部信息),也不一定三个都要写,写两个也是可以的。
4.如果不是以上三种类型。即如果视图函数返回的数据,不是字符串,也不是元组,也不是Response对象,那么就会将返回值传给` Response.force_type(rv,request.environ) `,然后再将`force_type`的返回值返回给前端。
自定义的`Response`对象的步骤
1. 继承自`Response`类。
2. 实现方法`force_type(cls,rv,environ=None)`。
3. 指定`app.response_class`为你自定义的`Response`对象。
如:自定义的`Response`对象将视图中返回的字典,转换成json对象,然后返回
class JSONResponse(Response):
@classmethod
def force_type(cls, response, environ=None):
"""
这个方法只有视图函数返回 非字符串 非Response对象 非元组时才会调用
response:视图函数的返回值
"""
if isinstance(response,dict):
response = jsonify(response)
#调用父类方法
return super(JSONResponse, cls).force_type(response,environ)
app.response_class = JSONResponse