Python-类视图和蓝图

目录

一.类视图

二.蓝图 


一.类视图

在Flask中,可通过视图函数展示视图

http://t.csdnimg.cn/r6IFG

也可基于类实现,类视图的好处是支持继承。标准类视图是继承flask.views模块中基类View的子类

from flask.views import View

该子类中必须重写View类中的dispatch_request()方法。除dispatch_request()方法外,我们也可以根据需要向View子类中添加其他方法或属性。

•methods属性:设置当前类视图可以处理的请求方式列表。

•dispatch_request()方法:用于实现处理不同HTTP请求的具体逻辑,该方法可以通过关键字参数接收URL传递的参数。

•as_view()方法:用于将类转换为实际视图函数。as_view()方法必须传入一个name参数,用于指定生成的视图函数名称,也可以根据需要传入一些关键字参数,这些参数都会转发给类的构造方法,以创建类的实例,并调用类内部的dispatch_request()方法。

如果希望类视图能够对浏览器发送的HTTP请求进行处理,那么需要将类视图与URL建立映射关系。我们需要通过add_url_rule()方法将类视图与URL进行映射,不过该方法的view_func参数不能直接传入类视图的名称,而是需要传入通过as_view()方法将类视图转换后的视图函数。

from flask import Flask
from flask.views import View
class MyView(View):                    # 定义类视图
    def dispatch_request(self, name):# 重写dispatch_request()方法
        return f'hello {name}'
app = Flask(__name__)
# 将类视图与URL规则进行映射
app.add_url_rule('/hello/<name>', view_func=MyView.as_view('myview'))
if __name__ == '__main__':
    app.run()

类视图中通过methods属性设置当前类视图可以处理的请求方式。例如,在上述示例的MyView类中,设置当前类视图处理GET请求和POST请求,并在dispatch_request()方法中添加处理GET请求的具体逻辑。

from flask.views import View
class MyView(View):                                  # 定义类视图
    methods = ['GET', 'POST']                     # 指定请求方式
    def dispatch_request(self, name):         # 重写dispatch_request()方法
        if request.method == 'GET':
            return f'hello {name}'
app = Flask(__name__)
# 将类视图与URL规则进行映射
app.add_url_rule('/hello/<name>', view_func=MyView.as_view('myview'))

基于方法的类视图

在Flask中,基于方法的类视图需要继承flask.views模块中的MethodView类,而MethodView类继承View类

from flask.views import MethodView

由于MethodView类中已经重写了dispatch_request()方法,所以定义基于请求方法的类视图时不需要重写dispatch_request()方法

-  在基于方法的类视图中,并非通过类属性methods来指定当前视图可以处理的请求方式,而是通过定义与请求方式同名的方法来处理不同的请求。例如,定义一个基于方法的类视图LoginView,之后在该类中添加处理GET请求和POST请求的方法

from flask import Flask
from flask.views import MethodView

class LoginView(MethodView):
    def get(self):                            # 处理GET请求
        return '我负责处理GET请求'
    def post(self):   	                      # 处理POST请求
        return '我负责处理POST请求'

app = Flask(__name__)

#基于方法的类视图同样需要使用add_url_rule()方法将类视图与URL规则进行映射,并将通过as_view()方法将类视图转换后的视图函数传入view_func参数。
app.add_url_rule('/login', view_func=LoginView.as_view('login'))

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

案例:

(1)在templates文件夹中添加一个用于展示用户登录页面的模板文件login.html

<body>
    <form action="" method=post>
        <span>用户名:</span><br>
        <input type=text name=username><br>
        <span>密码:</span><br>
        <input type=password name=password><br>
        <p><input type=submit value=登录></p>
    </form>
</body>

(2)在app.py文件中定义与使用基于方法的类视图

from flask.views import MethodView
from flask import Flask, render_template, request
class LoginView(MethodView):
    def get(self):                            # 处理GET请求
        return render_template('login.html')
    def post(self):   		 # 处理POST请求
        username = request.form.get('username')     # 获取输入的用户名
        password = request.form.get('password')     # 获取输入的密码
        if username =='flask' and password == '123': # 判断用户名和密码是否为123
            return f'用户:{username}登录成功。'
        else:
            return '用户名或密码错误,请重新登录。'
app = Flask(__name__)
app.add_url_rule('/login', view_func=LoginView.as_view('login'))

结果: 

二.蓝图 

蓝图是一种制作应用程序组件的方式,可以在应用程序内部或跨越多个项目使用。当分配请求时,Flask会将蓝图和视图函数关联起来,并生成两个端点之间的URL

- 若想在Flask程序中使用蓝图,首先需要创建蓝图,然后再对蓝图进行注册,其中创建蓝图需要通过Blueprint类实现;注册蓝图需要通过register_blueprint()方法实现。

flask.Blueprint(name, import_name, static_folder=None, static_url_path=None, template_folder=None, url_prefix=None, subdomain=None, url_defaults=None, root_path=None, cli_group=<object object>)

•name:必选参数,表示蓝图的名称。

•import_name:必选参数,表示蓝图包的名称,通常为__name__。

•static_folder:可选参数,表示静态文件夹的路径。

•static_url_path:可选参数,表示静态文件的URL。

•template_folder:可选参数,表示模板文件夹路径。

•url_prefix:可选参数,表示附加到所有蓝图URL的路径,用于与Flask应用程序的其他URL区分。

-假设Flask程序包含4个视图函数,分别属于普通用户和管理员两个子模块。如果在该程序中使用蓝图,那么使用蓝图前后的程序结构分别如下图:

在项目的根目录下创建两个py文件,分别是user.py和admin.py,在这两个文件中分别创建user蓝图和admin蓝图

user.py
from flask import Blueprint
# 创建蓝图
user = Blueprint('user', __name__) 
@user.route('/login')                  
def login():
    return 'user_login'
@user.route('/register')                  
def register():
    return 'user_register'


admin.py
from flask import Blueprint
# 创建蓝图
admin = Blueprint('admin', __name__) 
@admin.route('/login')               
def login():
    return 'admin_login'
@admin.route('/add')
def add():
    return 'admin_add'

- register_blueprint()方法用于将蓝图注册到Flask程序中。

register_blueprint(blueprint, url_prefix, subdomain, url_defaults,**options)

•blueprint:必选参数,表示要注册的蓝图。

•url_prefix:可选参数,表示附加到所有蓝图URL的路径,若在Blueprint类设置参url_prefix,则会被该参数值覆盖。

 - 在项目的app.py文件中使用register_blueprint()方法注册user蓝图和admin蓝图。

from admin import admin
from user import user
from flask import Flask
app = Flask(__name__)
app.register_blueprint(admin, url_prefix='/admin')  # 将蓝图admin进行注册
app.register_blueprint(user, url_prefix='/user')        # 将蓝图user进行注册
if __name__ == '__main__':
    app.run()

结果: 

  • 33
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,我对蓝图的理解相对通俗,就是觉得蓝图对于视图方法模块化、大项目协同开发过程中的一个很好的工具. 1.下图是我们通常情况下使用的项目组织结构 看一下视图方法: #views.py 1 from app import app 2 3 4 @app.route('/user/index') 5 def index(): 6 return 'user_index' 7 8 @app.route('/user/show') 9 def show(): 10 return 'user_show' 11 12 @app.route('/user/add') 13 def add(): 14 return 'user_add' 15 16 @app.route('/admin/index') 17 def adminindex(): 18 return 'admin_index' 19 20 @app.route('/admin/show') 21 def adminshow(): 22 return 'admin_show' 23 24 @app.route('/admin/add') 25 def adminadd(): 26 return 'admin_add' #从视图方法中,我们看到有6个视图,分别对应admin,user两个不同用户的3个功能index,add,show. 这样写显然没问题,但是明显与python提倡的模块化,优雅的代码特点相违背,即不是很pythonpython代码. 让我们在这里假想两个问题: 1.如果admin和user不止只有3个功能呢,比如好几百个,导致views的代码量已经达到了上万行? 2.如果我们有多个同事分工开发admin,user和其它可能的模块呢,都同时往一个views里写代码吗,在做版本控制时,提交过程中频繁出现提交冲突了怎么办? 3.加入我们要抛弃admin或者user功能块时怎么办,要一一手动删除所有admin或是user相关的代码吗,这样当然可以,但是会不会太low呢? 当然根据Pythonic特点,我们肯定希望尽可能的把代码尽量的模块化,让我们的代码看起来更加的优雅和顺畅,这个时候flask.Blueprint(蓝图)就派上用场了 什么是蓝图? 一个蓝图定义了可用于单个应用的视图,模板,静态文件等等的集合。 我什么时候会用到蓝图蓝图的杀手锏是将你的应用组织成不同的组件,比如把这里的admin,user相关的视图方法分为两个组件,一个是admin组件,一个是user组件.这时我们可以 创建两个蓝图实现这两个独立的组件. 2.我们如何使用蓝本将上述的视图方法看上去更加pythonic呢? 由于上面的例子中只有两个组件(模块)admin,user,我们可以创建名为admin.py和user.py的两个文件,分别在里面创建两个蓝图的实例对象admin,user. 直接上代码: #admin.py #admin.py from flask import Blueprint,render_template, request admin = Blueprint('admin',__name__) @admin.route('/index') def index(): return render_template('admin/index.html') @admin.route('/add') def add(): return 'admin_add' @admin.route('/show') def show(): return 'admin_show' #要想创建一个蓝图对象,你需要import flask. Blueprint() 并用参数 name 和 import_name 初始化。import_name通常用 __name__ ,一个表示当前模块的特殊的Python变量,作为 import_name 的取值。 #user.py from flask import Blueprint, render_template, redirect user = Blueprint('user',__name__) @user.route('/index') def index(): return render_template('user/index.html') @user.route('/add') def add(): return 'user_add' @user.route('/show') def show(): return 'user_show' 好了,视图函数已经分开了,我们如何使用它们的呢?再来看一下我们的views.py变成了什么样吧? #views.py from app import app from .admin import admin from .user import user #这里分别给app注册了两个蓝图admin,user #参数url_prefix='/xxx'的意思是设置request.url中的url前缀, #即当request.url是以/admin或者/user的情况下才会通过注册的蓝图视图方法处理请求并返回 app.register_blueprint(admin,url_prefix='/admin') app.register_blueprint(user, url_prefix='/user') #现在我们的views是否已经变得很简单了呢?顺便回答第三个问题,如果想弃用某一个组件(模块)我们只需要相对应的注释掉给app注册蓝图的行即可. #细心的伙伴还可以发现,在views.py中在使用默认endpoint的前提下,我们是没有办法使用同一个视图方法名的(当然我们也不建议在同一个文件中有两个视图方法名相同, #尽管指向他们的request.url不同),但是使用了蓝图之后我们就可以在不同模块中使用相同的方法名了,例如add,show.. 3.到此我们就可以通过浏览器测试我们的程序 4.附上使用蓝图后的项目组织结构 当然如果项目不大的话就没有什么必要使用蓝图了,甚至我们可以把除了所有css,js,html的代码都写到一个文件中去,这里我们不在举例,说明.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值