zoukankan      html  css  js  c++  java
  • 视图函数和视图类

    视图函数和视图类

    一、 视图函数

    之前我们已经了解过了视图函数的大概用法,本节深入了解一下视图函数

    img

    1.1 endpoint简介

    endpint参数是写在注册路由的装饰器中的一个参数,学名叫端点,我们可以理解为函数的别名。原来我们翻转视图函数的url的时候是直接通过是如函数的名字,如url_for('函数名'),现在我们可以指定一个endpoint='fbv'参数来进行翻转url。如果不指定endpoint,默认就以函数名作为端点名。

    实例:

    @app.route('/fbvtest/',methods=['GET','POST'],endpoint='fbv')  
    def fbvtest():
        url_demo = url_for('fbv')
        return '利用视图函数别名翻转的url为:{}'.format(url_demo)
    

    img

    关键词:

    • 利用@app.route()endpoint='fbv'参数可以自由指定端点名,url_for可以根据指定的端点名进行翻转。

    1.2 装饰器注册路由源码浅析

    (1) 首先写一个小视图函数

    #注册装饰器的原理
    #1 v = app.route('/source_code_demo/',endpoint='source_code')
    #2 v(source_code_demo)
    @app.route('/source_code_demo/',endpoint='source_code')
    def source_code_demo():
    
        return 'source_code_demo'
    

    (2) 查看app.route()源码

        ... 
        def route(self, rule, **options):
        ...
             def decorator(f):
                    endpoint = options.pop('endpoint', None)
                    self.add_url_rule(rule, endpoint, f, **options)
                    return f
                return decorator
    

    解析:

    • ,发现route()返回的是decorator函数地址,然后基于语法糖和装饰器的原理,decorator会加括号运行,像这样decorator(source_code_demo)
    • decorator函数中首先取出endpoint,然后运行self.add_url_rule(rule, endpoint, f, **options)
    • 所以 self.add_url_rule(rule, endpoint, f, **options)就是注册路由的核心

    (3) 点进self.add_url_rule(rule, endpoint, f, **options)查看源码,

    再点进_endpoint_from_view_func(view_func)查看源码

      ...
        
      @setupmethod
      def add_url_rule(self, rule, endpoint=None, view_func=None,
                         provide_automatic_options=None, **options):
            
      ...
    
           if endpoint is None:
                endpoint = _endpoint_from_view_func(view_func)
            options['endpoint'] = endpoint
            methods = options.pop('methods', None)
    
            # if the methods are not given and the view_func object knows its
            # methods we can use that instead.  If neither exists, we go with
            # a tuple of only ``GET`` as default.
            if methods is None:
                methods = getattr(view_func, 'methods', None) or ('GET',)
                
            ...
    
    def _endpoint_from_view_func(view_func):
        """Internal helper that returns the default endpoint for a given
        function.  This always is the function name.
        """
        assert view_func is not None, 'expected view func if endpoint ' 
                                      'is not provided.'
        return view_func.__name__
    

    解析:

    • 由上述代码我们可以直到如果没有指定endpoint,我们调用了 _endpoint_from_view_func()
    • 观察_endpoint_from_view_func函数我们可以知道,返回了视图函数的名字给了endpoint赋值
    • methos没有指定会给methos赋默认值('GET',)

    小结:

    1. self.add_url_rule(rule, endpoint, f, options)就是注册路由的核心
    2. 观察_endpoint_from_view_func函数我们可以知道,返回了视图函数的名字给了endpoint赋值
    3. methos没有指定会给methods赋默认值('GET',)

    img

    1.3 另一种注册路由的方式—app.add_url_rule()

    通过看上一个小节写的源码,现在我们知道了app.route() 的核心就是self.add_url_rule(rule, endpoint, f, options)就是注册路由的核心。所以我们可以直接使用app.add_url_rule()的方式来注册路由。

    实例:

    def add_url_test():
    
        return '实现了add_url方式注册路由'
                     # url                       端点                 函数地址
    app.add_url_rule('/add_url_test/',endpoint='add_demo',view_func=add_url_test)
    

    img

    1.4 视图函数中添加自定义装饰器

    我们在平时的开发的过程中,很多需要权限验证的功能需要用到装饰器,下面的代码是如何在flask中实现一个装饰器。

    from flask import Flask, request
    from functools import  wraps
    
    app = Flask(__name__)
    
    def login_verify(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            user_name = request.args.get('user')
            password = request.args.get('password')
            if user_name == 'mark' and password == '123':
                return func(*args,**kwargs)
            else:
                return '请登录'
        return wrapper
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    
    @app.route('/my_info/')
    @login_verify
    def my_info():
        return '个人信息页面'
    

    关键词

    1. 装饰器一定要写在注册路由的下面,写在视图函数的上面。
    2. 装饰器内部一定要使用@wraps(func)方法,用于保护被装饰函数的属性。

    img

    二、 视图类

    2.1 视图类的基本写法

    from flask import Flask, views, request, url_for
    from functools import wraps
    
    def login_verify(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            user_name = request.args.get('user')
            password = request.args.get('password')
            if user_name == 'mark' and password == '123':
                return func(*args,**kwargs)
            else:
                return '请登录'
        return wrapper
    
    
    class CBVTest(views.MethodView):
    
        methods = ['GET','POST']  # 指定可以接收的方法有什么
        decorators = [login_verify,]  # 指定自定义的装饰器
    
        def get(self):
            print(url_for('cbvtest'))
            return 'cbv_get'
        def post(self):
            return 'cbv_post'
    app.add_url_rule('/cbvtest',view_func=CBVTest.as_view(name='cbvtest'),endpoint='end_demo')
    

    讲解:

    1. 首先从flask中导入 views

    2. 写一个类一定要继承 views.MethodView

    3. 在类中写methods = ['GET','POST'] 可以指定可接受的请求类型

    4. 在类中写decorators = [login_verify,]可以指定装饰器,第一个装饰器是最里层函数依次往后包裹

    5. 在类中写def get(self):用于获取get请求

    6. 在类中写def post(self):用于获取post请求

    7. 添加路由的方法使用

      app.add_url_rule(
          '路由',view_func=CBVTest.as_view(name='自定义一个端点名字'))
      

      其原理是CBVTest.as_view(name='自定义一个端点名字')会返回一个函数,name是为这个函数命的名字,可以通过这个函数进行分发请求等操作。

    img

    三、 详细讲解注册路由的参数:

    常用的参数

    @app.route和app.add_url_rule参数:
    rule, URL规则
    view_func, 视图函数名称
    endpoint = None, 名称,用于反向生成URL,即: url_for('名称')
    methods = None, 允许的请求方式,如:["GET", "POST"]
    

    不常用的参数(了解)

    (1) 对URL最后的 / 符号是否严格要求 strict_slashes = False

    strict_slashes = False
        '''
            @app.route('/index', strict_slashes=False)
            #访问http://www.xx.com/index/ 或http://www.xx.com/index均可
            @app.route('/index', strict_slashes=True)
            #仅访问http://www.xx.com/index
        '''
    

    (2) 重定向到指定地址redirect_to=“ ”

    @app.route("/",redirect_to='/home/')
    def index():
    
        return '根路径'
    
    @app.route("/home/")
    def admin_demo():
    
        return 'home路径'
    

    (3) 为函数提供默认参数值

    defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}
    

    **(4)**子域名设置subdomain=“ ”

    from flask import Flask,url_for
    
    app = Flask(__name__)
    app.debug = True
    '''
    先在hosts设置域名解析(就是在本机的hosts文件上编辑上域名对应ip的关系) 
    域名解析会先解析本地如果没有再解析dns服务器
    C:WindowsSystem32driversetchosts
    
    127.0.0.1 mark.com
    127.0.0.1 admin.mark.com
    
    '''
    app.config['SERVER_NAME'] = 'mark.com:5000' # 这个代表访问这个域名的时候要访问5000端口
    
    @app.route("/")
    def index():
    
        return '设置域名成功'
    
    @app.route("/admin_demo/",subdomain='admin')
    def admin_demo():
    
        return '设置子域名成功'
    
    '''
    在浏览器中访问主域名
    mark.com:5000/
    
    在浏览器中访问子域名
    admin.mark.com:5000/admin_demo/
    
    注意:后面跟的path路径部分正常写
    '''
    
    if __name__ == '__main__':
        app.run(host='127.0.0.1',port=5000) # 测试服务器不稳定,尽量手动制定ip和端口
    

    img

    img

    img

    我把月亮戳到天上 天就是我的 我把脚踩入地里 地就是我的 我亲吻你 你就是我的
  • 相关阅读:
    Android Studio 开发
    Jsp编写的页面如何适应手机浏览器页面
    电影
    Oracle 拆分列为多行 Splitting string into multiple rows in Oracle
    sql server 2008 自动备份
    WINGIDE 激活失败
    python安装 错误 “User installations are disabled via policy on the machine”
    ble编程-外设发送数据到中心
    iOS开发-NSString去掉所有换行及空格
    ios9 字符串与UTF-8 互相转换
  • 原文地址:https://www.cnblogs.com/zhulipeng-1998/p/12863804.html
Copyright © 2011-2022 走看看