Flask视图函数与模板语法

Posted 编程面试宝典

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask视图函数与模板语法相关的知识,希望对你有一定的参考价值。

技术文章第一时间送达!



1.Django中的CBV模式

2.Flask中的CBV和FBV

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即FBV中的endpoint,指别名

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

类视图及其使用

视图函数不能面向对象编程,利用类视图来代替视图函数来解决这个问题

导入视图类 View

 from flask.views import View

编写一个视图子类

class MyView(View): # MyView继承于View

    def test(self):  #  自定义的方法
        return '测试类视图'

    def dispatch_request(self):   # 必须重写这个方法
        resp = self.test()
        return resp

利用View子类获取到一个视图方法

    MyView.as_view('test')

      注意:.as_view方法的放回值是一个方法,而且该方法的名字就是传进去的参数

将获取到的视图方法和路径对应起来

app.add_url_rule('/test/', view_func=MyView.as_view('test')) # MyView.as_view('test') 返回的是一个方法

类视图的原理

    把as_view方法返回的结果赋值给view_func
    as_view方法返回的是一个方法(注意:as_view方法传入的参数就是as_view返回的那个方法的名字),该方法会调用dispatch_request方法
    一旦路由进来,就会调用 dispatch_request 方法
    类视图的目的就是实现逻辑分离、方便管理

from flask import Flask
from flask.views import View

app = Flask(__name__)

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

class MyView(View): # MyView继承于View

    def test(self):  #  自定义的方法
        return '测试类视图'

    def dispatch_request(self):   # 必须重写这个方法
        resp = self.test()
        return resp


app.add_url_rule('/test/', view_func=MyView.as_view('test')) # MyView.as_view('test') 返回的是一个方法

print(app.url_map)

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

# 把as_view方法返回的结果赋值给view_func
# as_view方法返回的是一个方法(注意:as_view方法传入的参数就是as_view返回的那个方法的名字),该方法会调用dispatch_request方法
# 一旦路由进来,就会调用 dispatch_request 方法
# 类视图的目的就是实现逻辑分离、方便管理

方法视图及其使用

利用视图函数实现不同的请求执行不同的逻辑时比较复杂,需要在视图函数函数中进行判断;如果利用方法视图实现就比较简单

@app.route('/test/', methods=['GET', 'POST'])
def test():
    if request.method == 'GET':
        # 做GET的事情
        pass
    elif request.method == 'POST':
        # 做POST的事情
        pass
    return '测试'

导入方法视图类  
    from flask.views import MethodView

创建方法视图子类

class TestMethodView(MethodView):
    def get(self):
        # 处理Get请求
        return 'GET请求'
    def post(self):
        # 处理post请求
        return 'POST请求'

注意:视图类中的方法就是支持的请求类型

Flask视图函数与模板语法

利用方法视图子类创建一个视图函数
TestMethodView.as_view('testMethodView')
注意:as_view返回的是一个视图函数,而且该视图函数逇名称就是传进去的参数

将获取到的视图方法和路径对应起来
app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))

from flask import Flask
from flask import request
from flask.views import MethodView

app = Flask(__name__)

@app.route('/')
def index():
    return '测试主页面'

@app.route('/test/', methods=['GET', 'POST'])
def test():
    if request.method == 'GET':
        # 做GET的事情
        pass
    elif request.method == 'POST':
        # 做POST的事情
        pass
    return '测试'

class TestMethodView(MethodView):
    def get(self):
        # 处理Get请求
        return 'GET请求'
    def post(self):
        # 处理post请求
        return 'POST请求'

app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))
# method = TestMethodView.as_view('testMethodView');
# app.add_url_rule('/test02/<name>/', view_func=method, methods=['GET'])

print(app.url_map)

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

虽然在方法视图中定义的函数就是支持的请求类型,但是我们可以在配置路径时指定哪个路径对应哪中类型的请求

利用方法视图子类获取一个名字为testMethodView02的视图函数,该视图函数只能支持GET请求,而且支持转换器

method02 = TestMethodView.as_view('testMethodView02');
app.add_url_rule('/test02/<name>/', view_func=method02, methods=['GET'])

利用利用方法视图子类获取一个名字为testMethodView03的视图函数,该视图函数只能支持POST请求

method03 = TestMethodView.as_view('testMethodView03')
app.add_url_rule('/test03/', view_func=method03, methods=['POST'])

 模拟POST请求

Flask视图函数与模板语法

from flask import Flask
from flask import request
from flask.views import MethodView

app = Flask(__name__)

@app.route('/')
def index():
    return '测试主页面'

@app.route('/test/', methods=['GET', 'POST'])
def test():
    if request.method == 'GET':
        # 做GET的事情
        pass
    elif request.method == 'POST':
        # 做POST的事情
        pass
    return '测试'

class TestMethodView(MethodView):
    def get(self, name):
        # 处理Get请求, 也可以在这些方法中调用其他的方法
        return 'GET请求' + name
    def post(self):
        # 处理post请求, 也可以在这些方法中调用其他的方法
        return 'POST请求'

# app.add_url_rule('/test02/', view_func=TestMethodView.as_view('testMethodView'))
method02 = TestMethodView.as_view('testMethodView02');
app.add_url_rule('/test02/<name>/', view_func=method02, methods=['GET'])
method03 = TestMethodView.as_view('testMethodView03')
app.add_url_rule('/test03/', view_func=method03, methods=['POST'])

print(app.url_map)

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

六、请求与响应

from flask import Flask
 from flask import request
 from flask import render_template
 from flask import redirect
 from flask import make_response

    app = Flask(__name__)


    @app.route('/login.html', methods=['GET'"POST"])
    def login():

        # 请求相关信息
        # request.method
        # request.args
        # request.form
        # request.values
        # request.cookies
        # request.headers
        # request.path
        # request.full_path
        # request.script_root
        # request.url
        # request.base_url
        # request.url_root
        # request.host_url
        # request.host
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/' + secure_filename(f.filename))

        # 响应相关信息
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')

        # response = make_response(render_template('index.html'))
        # response是flask.wrappers.Response类型
        # response.delete_cookie('key')
        # response.set_cookie('key', 'value')
        # response.headers['X-Something'] = 'A value'
        # return response


        return "内容"

    if __name__ == '__main__':
        app.run() 
#######################################################################################

from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
from urllib.parse import urlencode,quote,unquote
app = Flask(__name__)

@app.route('/index',endpoint='xx')
def index():
    from werkzeug.datastructures import ImmutableMultiDict
  =================
    # get_data = request.args
    # get_dict = get_data.to_dict()
    # get_dict['xx'] = '18'
    # url = urlencode(get_dict)
    # print(url)
  ====================
    # print(request.query_string)
    # print(request.args)
  ==========================
    # val = "%E6%8A%8A%E5%87%A0%E4%B8%AA"
    # print(unquote(val))   #把上面这样的数据转换成中文
    #
    # return "Index"

    # return "Index"
    # return redirect()
    # return render_template()
    # return jsonify(name='alex',age='18')  #相当于JsonResponse
  =======================
    response = make_response('xxxxx')   ##如果是返回更多的值,cookie,headers,或者其他的就可用它
    response.headers['xxx'] = '123123'
    return response


if __name__ == '__main__':
    # app.__call__
    app.run()

七、模板语法

1、模板的使用

Flask使用的是Jinja2模板,所以其语法和Django无太大差别

Flask中模板里面,执行函数时,需要带()才执行

1.为了防止xss攻击,加了验证,所以页面上显示字符串的形式,解决办法,有两种方法

方法一:在后端使用Markup,等价于Django里的mark_safe

 v = Markup("<input type='text' />")

方法二:在前端使用safe

{{ v1|safe }}

2.静态文件的两种导入方式 

目录结构:

Flask视图函数与模板语法

方式一:

Flask视图函数与模板语法

方式二:

Flask视图函数与模板语法

3.flask中模板语法不提示,解决办法

点击选择jinja2

2、自定义模板方法

Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,

run.py

from flask import Flask,url_for,render_template,Markup
app = Flask(__name__)

def test(a,b):    #自定义的标签,此方法在使用时,需要在render_temlate中传入到指定以页面使用
    return a+b

@app.template_global()   # 不需要传入,可直接在页面使用
def sb(a1, a2):
    return a1 + a2 + 100


@app.template_filter()    #不需要传入,使用时要在一个值(此值作为第一个参数传入到过滤器中)的后面加入|,然后再加参数
def db(a1, a2, a3):
    return a1 + a2 + a3

@app.route('/index')
def index():
    v1 = "字符串"
    v2 = [11,22,33]
    v3 = {"k1":"v3","sdf":"sdgfgf"}
    v4 = "<input type='text' />"
    v5 = Markup("<input type='text' />")
    return render_template("index.html",v1=v1,v2=v2,v3=v3,v4=v4,v5=v5,test=test)

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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
</head>
<body>
{{ v1 }}
<ul>
    {% for foo in v2 %}
       <li>{{ foo }}</li>
    {% endfor %}
    {{ v2.1 }}

    {% for k,v in v3.items() %}
    <li>{{ k }} {{ v }}</li>
    {% endfor %}
    {{ v3.k1 }}
    {{ v3.get("k1") }}

    {{ v4|safe }}
    {{ v5 }}

    <h1>{{ test(1,2) }}</h1>
    <p>{{ sb(1,2) }}</p>
    <p>{{ 1| db(2,3) }}</p>
</ul>
</body>
</html>

PS:模板继承的方法和django的一样。

3.宏

只有定义的东西在很多地方去使用的时候才去用它,

html

{% macro xx(name, type='text', value='') %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
  <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
  <input type="{{ type }}" name="{{ name }}" value="{{ value }}">

{% endmacro %}

{{ xx('n1') }} 

相当于在页面上定义了一个名为xx的'函数',这个函数接收3个参数,我们给type和value写上了默认值,此时调用,我们还需要传入一个参数,我们此时传入了一个n1,则

页面上会生成3个input框,name都为n1

原文链接:

https://www.cnblogs.com/huchong/p/8227606.html



识别图中二维码,欢迎关注python宝典

以上是关于Flask视图函数与模板语法的主要内容,如果未能解决你的问题,请参考以下文章

flask模板

Flask之勾子,错误捕获以及模板语法

Flask之视图,会话模板

flask快速入门笔记四_模板:分离数据与视图

初识 flask

5. Flask模板