Day 2
自定义url转换器
之前有提到在视图函数的路径中可以出现不同类型的变量,但是普通的变量类型还是太少了,那么要怎么接受自己需要的类型呢?这里给出的方法是自定义一个转换器。比如下面给出的转换器可以识别变量类型是否为合法的11位电话号码
class TelConverter(BaseConverter): regex = r'1[34578]\d{9}' # 不要忘了把定义完的转换器添加到url_map中 app.url_map.converters['tel'] = TelConverter @app.route(/tel/<tel:tel_num>/) def tel_num(tel_num): return 'Your tel is %s' %tel_num
to_python方法:
转换器接收到符合需要的类型的参数后就会把参数传递给视图函数去进行调用。那如果在接收到参数之后相对参数做一些处理再拿到视图函数里去用该怎么办呢?答案是在转换器中重写 to_python() 方法
#to_python的返回值将会作为对应视图函数中实际的参数 class ListConveter(BaseConverter): def to_python(self, value): return value.split('+') app.url_map.converters['list'] = ListConverter @app.route(/list/<list:my_list>/) def lst(my_list): return 'Your list is ' + my_list #url = 127.0.0.1:5000/list/a+b/ #显示 Your list is ['a','b']
to_url方法:
之前提到使用url_for找视图函数所对应的路径,其用法为url_for('endpoint',**value=),其中value就是路径中对应的参数。与 to_python 对应,如果你想对查找的路径中的参数做一定的处理,则可以在转换器中重写to_url方法
#to_url会把返回值作为url_for('函数名',变量)中的实际的变量 #上例中若定义to_url(),比如 def to_url(self, value): return '+'.join(value) ''' 则使用 url_for('lst',my_list=['a','b']) 返回的结果为 /list/a+b/ 对比不使用to_url()返回的结果为/list/%5B%27a%27%2C%20%27b%27%5D/ '''
页面跳转和重定向
顾名思义,就是你在点击一个页面时因为某些原因自动跳转到另一个页面,具体又有以下两类。
永久性重定向:http状态码为301,多用于旧网址被废弃要转到新页面
暂时性重定向:http状态码为302。比如访问一个要权限的网页但是用户并 没有登录这种情况。
在flask中通过 flask.redirect(location, code=302) 来实现,例:
@app.route('/login/') def login(): return 'This is the login page.' @app.route('/profile/') def profile(): if request.args.get('name'): return 'Personal profile page.' else: return redirect(url_for('login'), code=302)
关于响应(Response)
或许读者已经注意到,之前的视图函数都带有return值,且不能为空。那么为什么return的值能被浏览器所接受并显示出来呢?其实视图函数返回值会自动转为一个响应对象,flask转换逻辑如下:
· 如果是合法的响应对象,则直接返回
· 如果是string,那么flask会重新创建一个werkzueg.warppers.Response对 象,Response以该字符串为主体,状态码200, mime类型为text/html,然后返 回Response对象,即:
return 'hello'
||
return Response('hello',status=200,mimetype='text/html')
· 如果返回元组,元组中数据类型是(response,status,headers),status会覆盖默认状态码200,headers可以是字典或列表,作为额外消息头。
· 如果都不满足,则会调用Response.force_type(rv,request.environ)转为响应对象
比如现在要返回一个字典类型的值,但是它不能进行默认的转换,那么我们就要来自定义一个响应对象,重写force_type()函数,来实现对字典的处理
#自定义响应对象 class JSONResponse(Response): @classmethod def force_type(cls, response, environ=None): ''' response:视图函数的返回值 只有在非string、tuple、Response对象时才会调用此函数 ''' if isinstance(response, dict): response = jsonify(response) # import jsonify return super(JSONResponse, self).force_type(response,environ) return "Can't response" app.response_class = JSONResponse