Flask 框架学习

Flask 框架学习,第1张

Flask 框架学习 页面跳转和重定向 什么是重定向?

重定向在页面上的表现就是浏览器从一个页面自动跳转到另外一个页面。
比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,此时应该重定向到登录页面。

重定向的分类:

永久重定向: http的状态码是301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,一个典型的例子是你输入旧的网址会自动跳转到新的网址,这种情况下应该用永久重定向。

临时重定向: http的状态码是302,表示页面的暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。

HTTP状态码分类:
HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599):

redirect()函数实现重定向

在flask中,重定向是通过flask.redirect(url, code=302)这个方法来实现的,url表示需要重定向到的URL,可以结合url_for()函数来使用,code表示重定向类型状态码,默认是302也即暂时性重定向,可以修改成301来实现永久性重定向。

示例:模拟访问个人中心页面,未携带name参数而重定向到登录页面

from flask import Flask,url_for,request,redirect

app = Flask(__name__)


@app.route('/')
def index():
    return 'Hello World'


@app.route('/article/')
def article_list(aid):
    return 'article %s' % aid

@app.route('/login/')
def login():
    print(request.form.get('name'))
    return 'login'

@app.route('/profile/')
def profile():
    name = request.args.get('name')
    if name:
        return name
    else:
        return redirect('/login')

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


示例如下:
未传入name的URL:http://127.0.0.1:5000/profile/
传参name的URL:http://127.0.0.1:5000/profile/?name=123

通过示例可以看到,请求中未携带name的参数会自动重定向到登录页面。

控制台显示:

可以发现请求状态码为:302
通过上面的例子发现重定向到login时不够灵活,如果登陆地址发生改变就需要同步修改代码。此时就可以用url_for()方法,来传入方法名而不是路由地址,即便地址改变,也可以正常重定向。
示例:

from flask import Flask,url_for,request,redirect

app = Flask(__name__)

@app.route('/login/')
def login():
    print(request.form.get('name'))
    return 'login'

@app.route('/profile/')
def profile():
    name = request.args.get('name')
    if name:
        return name
    else:
        # return redirect('/login')
        return redirect(url_for('login'))  # 重定向

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

注意:修改状态码为301,示例:redirect(url_for('login'), code=301)

函数的返回值——响应(Response) 什么叫响应和视图函数?

响应:
前面的index()函数注册为程序跟地址的处理程序。如果部署程序的服务器域名为www.example.com,在浏览器中访问http://www.example.com后,会触发服务器执行index()函数,这个函数的返回值就称为响应,是客户端收到的内容。如果客户端是Web浏览器,响应就是显示给用户查看的文档。
视图函数:
视图函数就是像index()这样的函数,视图函数返回的响应可以是包含HTML的简单字符串,也可以是复杂的表单。

视图函数中可以返回值的类型:

Response对象
如果返回是一个合法的响应对象(Response), 则直接返回。

字符串
如果返回值一个字符串, 那么flask会重新创建一个"werkzeug.wrapper.Response"对象, Response将该字符串作为主体, 状态码为200, MIME类型为 text/html, 然后返回该Response对象

元组
传入元组的格式是(response,status,headers),response为一个字符串,status值是状态码,header可以是一个列表或者字典, 作为额外的消息头。

字典
如果返回的是一个字典,那么调用 jsonify 创建一个响应对象(也可以直接返回)

其他
如果以上条件都不满足, flask会假设返回值是一个合法的WSGI 应用程序 并通过"Response.force_type(rv, request, environ)转换为一个请求对象"

示例: 返回字符串:

返回字符创等同于:

示例: 直接返回字典:

from flask import Flask

app = Flask(__name__)
app.debug = True

@app.route('/list3/')
def list3():
    a = {'username': 'xiaoming', 'age': 18}
    return a


if __name__ == "__main__":
    app.run(host='127.0.0.1', port=5000)

显示结果:

Response.force_type 方法重写

视图函数返回响应Response给浏览器,一般来说只能是String和固定格式的Tuple,当然也可以自定义,但无论是返回哪种数据格式,最终都是被包装成一个Response对象返回给浏览器的。返回的是String时,其实也是被包装成Response对象返回给浏览器的。也可以是一个固定格式的Tuple(元组):(Response, status, headers),即响应体、状态码和头信息的Tuple,可以只返回一个Response,或者两个(Response, status),或者全部返回(Response, status, headers)。当可以自定义返回的响应体时需要注意以下几点:

    Response子类:自定义的Response子类必须继承自from flask import Response。response_class:使用app.response_class=MyResponse使之生效(例如: app.response_class=自定义类名)。force_type(response, environ=None):当返回的数据类型,既不是字符串,也不是元组时(字典也可以直接返回),flask就会调用Response的force_type方法来处理,如果不能处理就会返回错误,所以Response子类一般是需要重写这个方法来返回一个合法的数据,参数response传入的不合法的数据,也可以经过处理后返回一个合法的Response对象。

示例返回字典:

from flask import jsonify, Response
from flask import Flask

app = Flask(__name__)
app.debug = True


class JSONResponse(Response):

    @classmethod
    def force_type(cls, response, environ=None):
        """
        这个方法只有视图函数返回非字符串,非元组,非Response对象时才会调用
        """
        if isinstance(response, dict):
            # 如果视图函数返回的是一个字典,就把response转换成json对象
            # jsonify()不仅可以将字典转换成json对象,还将该对象包装成了一个Response对象
            response = jsonify(response)
        return super(JSONResponse, cls).force_type(response, environ)


app.response_class = JSonResponse


@app.route('/list3/')
def list3():
    a = {'username': 'xiaoming', 'age': 18}
    a = dict(a)
    return a


if __name__ == "__main__":
    app.run(host='127.0.0.1', port=5000)

显示:

示例返回列表:

from flask import Flask, Response

app = Flask(__name__)


class MyResponse(Response):
    """自定义Response类"""
    @classmethod
    def force_type(cls, response, environ=None):
        """重写force_type方法,当参数既不是字符串,
        也不是(Response, status, headers)元组时会调用此方法"""
        if isinstance(response, list):
            response = Response('+'.join(response))

        # 这里需要包装成Response对象才能传入父类的force_type中,
        # 只传字符串会报错
        return super().force_type(response, environ)


# 指定自定义的Response类,使之生效
app.response_class = MyResponse


@app.route('/listresponse/')
def list_response():
    # 返回一个不合法的数据
    # 如果没有自定义的Response类来处理的话,就会报错
    return ['python', '36']


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

示例返回元组:

    返回元组时,只返回元组的第一个元素;在一般情况下,返回元组的用法是return '关于我们',200,即return '字符串',状态码。
from flask import Flask,url_for,request,redirect,Response

app = Flask(__name__)

@app.route('/about')
def about():
   return Response('关于我们')

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

Response(‘关于我们’)相当于Response(‘关于我们’,status=200,mimetype=‘text/html’)。Response的用法是Response(‘字符串’,状态码,mimetype=’’)

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5701120.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存