Flask之视图高级(二)

简介: Flask之视图高级(二)

目录


类视图&装饰器


基于调度方法的类视图


基于调度方法的类视图写法优化


视图装饰器的使用


蓝图


蓝图的介绍


使用方法


蓝图的url前缀:


蓝图的目录结构


蓝图模板的使用


templates的寻找规则


蓝图静态文件


蓝图内部静态文件


蓝图与url_for函数的结合


蓝图设置子域名


蓝图实现子域名




类视图&装饰器


基于调度方法的类视图


1.基于调度方法的类视图,可以根据不同的method来执行不同的请求。假如用户发送的get请求,则会自动执行这个类get方法。


2.将get请求相关的代码放在get方法中,与post请求相关的代码都放在post方法中,就不需要通过之前的request.method  == ‘GET’  了。可以让代码更加的简洁,方便。


这是未使用调度方法类视图的原代码:


可以看到,现在完美使用的方法需要写method=【‘post’,‘get’】以及逐个判断是否为post或者get请求。

from flask import Flask,render_template,request
app = Flask(__name__)
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'GET':
        return render_template('login05.html')
    elif request.method == 'POST':
        uname = request.form.get('uname')
        pwd = request.form.get('pwd')
        if uname == 'xiaolin' and pwd == '123456':
            return '登录成功!'
        else:
            return render_template('login05.html')
if __name__ == '__main__':
    app.run(debug=True)

改进后:


不需要对请求类型进行判断。

from flask import Flask,render_template,request
from flask.views import MethodView
app = Flask(__name__)
class loginView(MethodView):
    def get(self):
        return render_template('login05.html')
    def post(self):        
        uname = request.form.get('uname')
        pwd = request.form.get('pwd')
        if uname == 'xiaolin' and pwd == '123456':
            return '登录成功!'
        else:
            return render_template('login05.html',msg='用户名或者密码错误!')
app.add_url_rule('/login/',view_func=loginView.as_view('login'))
if __name__ == '__main__':
    app.run(debug=True)

基于调度方法的类视图写法优化


优化写法:

from flask import Flask,render_template,request
from flask.views import MethodView
app = Flask(__name__)
class logView(MethodView):
    def _jump(self,msg = None):
        return render_template('login06.html',msg = msg)
    def get(self,msg = None):
        return self._jump()
    def post(self):
        uname = request.form.get('uname')
        pwd = request.form.get('pwd')
        if uname == 'xiaolin' and pwd == '123456':
            return '欢迎小林'
        else:
            return self._jump(msg = '用户名或者密码错误!请输入正确的的用户名和密码!')
app.add_url_rule('/login/',view_func=logView.as_view('login'))
if __name__ == '__main__':
    app.run(debug=True)

其实主要是 render_template()这里出现了重复,可以创建一个函数单独写出去,在进行调用即可。在多次要使用重复代码的时候,可以使用,以减少代码量。


视图装饰器的使用


python装饰器:用于扩展原来函数的功能的函数,特殊之处在于它的返回值是一个函数。


优点:在不用更改原函数的代码的前提下,给函数增加新的功能。


注意:在视图函数中使用自定义装饰器,必须放在app.route()下,否则这个装饰器将不起任何作用。


例:


一个验证用户是否登录成功的装饰器 ,会将登录成功或者失败的信息传递给后台。

from flask import Flask,render_template,request
from functools import wraps
import logging
app = Flask(__name__)
# 设置日志模块
logging.basicConfig(level=logging.INFO)
def login_required(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        uname = request.args.get('uname')
        pwd = request.args.get('pwd')
        if uname == 'xiaolin' and pwd == '123456':
            logging.info(f'{uname}:登录成功!!')
            return func(*args,**kwargs)
        else:
            logging.info(f'{uname}:尝试登录失败!!')
            return '用户名或密码错误!'
    return wrapper
@app.route('/')
@login_required
def index():
    return 'hello'
if __name__ == '__main__':
    app.run(debug=True)

在类视图中使用装饰器,需要重写类视图的一个类属性decorators,这个类属性是一个列表或者元组都可以,里面装的就是所有的装饰器。

@app.route('/')
@login_required
def index():
    return 'hello'
class LoginViwe(MethodView):
    decorators=[login_required]
    def get(self):
        return 'hello'
app.add_url_rule('/login/',view_func=LoginViwe.as_view('login'))

蓝图


蓝图里老是映射来映射去,烦死了有时候都搞不清楚了。


蓝图的介绍


蓝图我个人理解的话就是一个容器。


在Flask中,使用蓝图Blueprint来分模块组织管理。


那么它具有以下的特点:


一个应用可以具有多个Blueprint

可以将一个Blueprint注册到任何一个未使用的URL下比如“/user”、“/goods”

Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的

在一个应用初始化时,就应该要注册需要使用的Blueprint

注意


Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中


以一个简单的购物页面来看:

     

#用户模块


   #登录模块


   #注册模块


   #退出模块


#产品模块  


   #获取全部产品


   #获取单件产品


   #更新产品


   #删除产品


   #批量添加产品


#收藏模块


#购物车模块


可以看到就单单几个模块就以及足够复杂了,所需要的代码量是很大的了。当产品模块需要更改的时候,时间也是很费劲的。而且若是书写不规范的模块或者耦合性高的模块间,需要修改更加费时费力。


这时候蓝图就很重要了,每一个模块都能单独创建一个蓝图来批量管理里面的子模块,不需要的时候可以直接删除该文件夹。


使用方法


1.创建一个蓝图对象(这里是用户模块):

user_pb = breakpoint('user',__name__)

2.给蓝图创建一个需要管理的蓝图地址:

@user_pb.route('/login/')
def login():
    return '登录模块'
@user_pb.route('/register/')
def register():
    return '注册模块'

3.需要注册这个蓝图对象:

app.register_blueprint(user_pb)

蓝图的url前缀:


可以为蓝图添加一个独特的前缀,增加辨识度。

app.register_blueprint(user_bp, url_prefix='/user')

蓝图的目录结构


在接着上一个蓝图的使用后,现在完美仍然将蓝图放在一个文件里边,造成的结果就是仍然显得很臃肿和复杂。那么为了让每个模块更加清晰,可以通过将代码分在不同的文件里进行集中管理。

2558944110c545c68d71f4e743f776fb.png

可以根据功能模块和技术模块分别创建工程目录,不多赘述。


蓝图模板的使用


templates的寻找规则


  • 如果项目中的templates文件夹中有相应的模版文件,就直接使用了。

  • 如果项目中的templates文件夹中没有相应的模版文件,那么就到在定义蓝图的时候指定的路径中寻找。

  • 并且蓝图中指定的路径可以为相对路径,相对的是当前这个蓝图文件所在的目录


在正常情况下,蓝图文件在寻找模块文件时,会以templates为根目录来进行查询。

user_bp = Blueprint('user',__name__,url_prefix='/user',template_folder='user_page')

蓝图静态文件


模板中可以有独有的静态文件


蓝图内部静态文件


蓝图对象创建时不会默认注册静态目录的路由。需要我们在创建时指定 static_folder 参数。


例:


将蓝图目录下的static_admin目录设置为静态目录

user=Blueprint("user",__name__,static_folder='user_static')
app.register_blueprint(admin,url_prefix='/user')
<body>
  <h1>模板静态文件</h1>
  <video src="/user/user_static/aaa.mp4" autoplay width="50%" loop="loop" muted='muted'></video>
</body>

777.png

可以通过static_url_path改变访问,这个就不做实例了。


蓝图与url_for函数的结合


跟以往不同,在蓝图中使用url_for跟默认写法不同,需要在url_for后边指定蓝图的名字。


app类中、模版中、同一个蓝图类中都是如此。否则就找不到这个endpoint


在python中:

from user import user_bp
from flask import url_for
@user_bp.route('/index/')
def index():
    return '用户主页'
@user_bp.route('/')
def test_url():
    return url_for('user.index')

在html中:

    <video src='{{url_for("user.static",filename="aaa.mp4")}}' autoplay muted="meted" loop="loop"></video>

蓝图设置子域名


很多应用都带有子应用,比如百度里的百度地图,百度贴吧,百度新闻等等。子应用的域名基本上相等,但是前缀不同,可以利用蓝图来实现子域名。


蓝图实现子域名


1.使用蓝图技术。


2.创建蓝图对象的时候,添加一个传递一个subdomain参数,来指定子域名的前缀:

cms_bp= Blueprint('cms',__name__,subdomain='cms')

3. 需要在主app文件中,需要配置app.config的SERVER_NAME参数。

if __name__ == '__main__':
    # 127.0.0.1:5000
    app.config['SERVER_NAME'] = 'xiaolin.com:5000'
    app.run(debug=True)

 4.在windows:C:\Windows\System32\drivers\etc下,找到hosts文件,然后添加域名与本机的映射。Linux: /etc/hosts。


域名和子域名都需要做映射。


这个很烦啊!!!!!!!


这样改(例):


127.0.0.1 xiaolin.com


127.0.0.1 python.xiaolin.com


注意


  • ip地址不能有子域名

  • localhost也不能有子域名

————————————————————————————————————————

Flask之视图高级---->END

相关实践学习
基于函数计算快速搭建Hexo博客系统
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
1天前
|
JSON 数据处理 数据库
Flask视图函数与响应处理的艺术
【4月更文挑战第15天】本文探讨了Flask框架中视图函数和响应处理的原理与实践。视图函数通过`@app.route()`装饰器与URL关联,处理用户请求并返回响应。示例展示了如何从URL或请求对象获取参数,以及执行不同操作后返回响应。Flask支持字符串、元组和响应对象等多种响应类型。最佳实践包括保持视图函数简洁、使用模板引擎、处理异常和设置正确状态码。掌握这些技能能提升Web应用的用户体验和开发效率。
|
1天前
|
网络架构 Python
Flask路由与视图:构建你的第一个Web应用
【4月更文挑战第15天】Flask是Python的Web框架,其核心是路由和视图。路由通过`@app.route()`装饰器定义,将URL映射到视图函数。视图函数处理请求并返回响应。动态路由允许URL包含可变部分,如`&lt;username&gt;`,将参数传递给函数。本文通过示例展示了如何创建显示待办事项列表的Web应用,包括定义路由、视图、使用模板以及运行应用。这为基础的Flask应用开发提供了基础。
|
9月前
|
JSON 安全 数据格式
Flask 高级应用:使用蓝图模块化应用和 JWT 实现安全认证
本文将探讨 Flask 的两个高级特性:蓝图(Blueprints)和 JSON Web Token(JWT)认证。蓝图让我们可以将应用模块化,以便更好地组织代码;而 JWT 认证是现代 Web 应用中常见的一种安全机制。
|
9月前
|
Python
【flask】URL和视图映射
【flask】URL和视图映射
37 0
|
9月前
|
搜索推荐 Apache Python
Flask | Flask基础 - URL与视图
Flask | Flask基础 - URL与视图
|
10月前
|
存储 数据库 Python
Flask高级(四)
Flask高级(四)
|
10月前
|
算法 开发者 Python
Flask高级(三)
Flask高级(三)
|
10月前
|
Python
Flask高级(二)
Flask高级(二)
|
10月前
|
Web App开发 存储 安全
Flask高级(一)
Flask高级(一)
|
10月前
|
Python
Flask之视图高级(一)
Flask之视图高级(一)