as_views

本文解析了Django中类视图的工作原理,包括as_view方法如何返回闭包以匹配HTTP请求方法,以及dispatch方法如何分发请求。
  • as_view逻辑:返回一个闭包——>闭包会在Django解析完请求后调用
    + 闭包的逻辑:
    + 给class(定义的view类)赋值–request,args,和kwargs
    + 根据HTTP方法分发请求

    • 请求到达后的完整逻辑
      1. 调用dispatch分发
      2. 接着调用GET方法
        1. 在GET请求中,首先调用get_queryset方法,拿到数据源
        2. 接着调用get_context_data方法,拿到了需要渲染到模板中的数据
          • 1)在get_context_data中,首先调用get_paginate_by拿到每页数据
          • 2)接着调用get_context_object_name拿到要渲染到模板中的这个quertset名称
          • 3)然后调用paginate_queryset进行分页处理
          • 4)最后拿到的数据转为dict并返回
        3. 调用render_to_response渲染数据到页面
          • 1)在render——to_response中调用get_template_names拿到模板名
          • 2)然后把request,context,template_name等传递到模板中
            django的类视图拥有自动查找指定方法的功能, 通过调用是通过as_view()方法实现

urls.py

from meduo_mall.demo import views

urlpatterns = [
url(r’register/$’, views.Demo.as_view())
]
views.py

from django.views.generic import View

class Demo(View):

def get(self, request):
    return HttpResponse('get page')

def post(self, request):
    return HttpResponse('post page')

为什么as_view能自动匹配指定的方法,

先看源码

@classonlymethod
def as_view(cls, **initkwargs):  # 实际上是一个闭包  返回 view函数
    """
    Main entry point for a request-response process.
    """
    for key in initkwargs:
        if key in cls.http_method_names:
            raise TypeError("You tried to pass in the %s method name as a "
                            "keyword argument to %s(). Don't do that."
                            % (key, cls.__name__))
        if not hasattr(cls, key):
            raise TypeError("%s() received an invalid keyword %r. as_view "
                            "only accepts arguments that are already "
                            "attributes of the class." % (cls.__name__, key))

    def view(request, *args, **kwargs):  # 作用:增加属性, 调用dispatch方法 
        self = cls(**initkwargs)  # 创建一个 cls 的实例对象, cls 是调用这个方法的 类(Demo)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request  # 为对象增加 request, args, kwargs 三个属性
        self.args = args
        self.kwargs = kwargs
        return self.dispatch(request, *args, **kwargs)  # 找到指定的请求方法, 并调用它
    view.view_class = cls
    view.view_initkwargs = initkwargs

    # take name and docstring from class
    update_wrapper(view, cls, updated=())

    # and possible attributes set by decorators
    # like csrf_exempt from dispatch
    update_wrapper(view, cls.dispatch, assigned=())
    return view

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    if request.method.lower() in self.http_method_names:  # 判断请求的方法类视图是否拥有, http_method_names=['get', 'post']
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)  # 如果存在 取出该方法
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)  # 执行该方法

简化版

@classonlymethod
def as_view(cls, **initkwargs):  # 实际上是一个闭包  返回 view函数
    """
    Main entry point for a request-response process.
    """
    def view(request, *args, **kwargs):  # 作用:增加属性, 调用dispatch方法 
        self = cls(**initkwargs)  # 创建一个 cls 的实例对象, cls 是调用这个方法的 类(Demo)
        if hasattr(self, 'get') and not hasattr(self, 'head'):
            self.head = self.get
        self.request = request  # 为对象增加 request, args, kwargs 三个属性
        self.args = args
        self.kwargs = kwargs
        return self.dispatch(request, *args, **kwargs)  # 找到指定的请求方法, 并调用它

    return view

def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    if request.method.lower() in self.http_method_names:  # 判断请求的方法类视图是否拥有, http_method_names=['get', 'post']
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)  # 如果存在 取出该方法
    else:
        handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs)  # 返回该请求方法执行的结果

再简化

def as_view(): # 校验 + 返回view方法
# 一些校验

def view(): # 执行视图
# 增加 为对象request, args, kwargs 属性

return dispatch() # 调用指定的请求方法
return view

def dispatch(): # 真正的查找指定的方法, 并调用该方法

return handler()
调用顺序: as_view --> view --> dispatch
可以看出as_view实际上是一个闭包, 它的作用做一些校验工作, 再返回view方法.

而view方法的作用是给请求对象补充三个参数, 并调用 dispatch方法处理

dispatch方法查找到指定的请求方法, 并执行

可以得出结论: 实际上真正实现查找的方法是 dispatch方法

<think>我们正在查看Oracle数据库中的`USER_VIEWS`数据字典视图,该视图存储了当前用户所拥有的视图的定义信息。 根据引用[1]中关于`ALL_VIEWS`的列描述,我们可以推断`USER_VIEWS`有类似的列(因为`USER_VIEWS`是`ALL_VIEWS`的一个子集,只包含当前用户拥有的视图)。 注意:`USER_VIEWS`视图与`ALL_VIEWS`视图结构相同,但不包含`OWNER`列(因为当前用户就是所有者)。 下面列出`USER_VIEWS`视图的主要字段及其含义: 1. **VIEW_NAME**: - 数据类型:`VARCHAR2(30)` - 说明:视图的名称(注意:在数据字典中,名称默认以大写形式存储)。 2. **TEXT_LENGTH**: - 数据类型:`NUMBER` - 说明:视图定义(即创建视图的SQL语句)的长度(以字节为单位)。 3. **TEXT**: - 数据类型:`CLOB` - 说明:视图的完整定义SQL语句(即创建视图时使用的SELECT语句)。由于视图定义可能很长,所以使用CLOB类型存储。 4. **TYPE_TEXT_LENGTH** (11g及以后版本): - 数据类型:`NUMBER` - 说明:类型视图的定义长度(仅当视图是类型视图时有效,普通视图此列为空)。 5. **TYPE_TEXT** (11g及以后版本): - 数据类型:`CLOB` - 说明:类型视图的定义(仅当视图是类型视图时有效)。 6. **OID_TEXT_LENGTH** (11g及以后版本): - 数据类型:`NUMBER` - 说明:对象标识符(OID)子句的长度。 7. **OID_TEXT** (11g及以后版本): - 数据类型:`CLOB` - 说明:对象标识符(OID)子句的文本。 8. **VIEW_TYPE_OWNER** (11g及以后版本): - 数据类型:`VARCHAR2(30)` - 说明:如果视图是类型视图,则此列表示类型的所有者。 9. **VIEW_TYPE** (11g及以后版本): - 数据类型:`VARCHAR2(30)` - 说明:如果视图是类型视图,则此列表示类型名称。 10. **SUPERVIEW_NAME** (11g及以后版本): - 数据类型:`VARCHAR2(30)` - 说明:如果视图是子视图,则此列表示其父视图(超视图)的名称。 11. **EDITIONING_VIEW** (12c及以后版本): - 数据类型:`VARCHAR2(1)` - 说明:指示视图是否为版本化视图(Editioning View),取值为'Y'或'N'。 12. **READ_ONLY** (12c及以后版本): - 数据类型:`VARCHAR2(1)` - 说明:指示视图是否为只读视图,取值为'Y'或'N'。 注意:不同版本的Oracle数据库可能包含不同的列。上述列中,前3个(VIEW_NAME, TEXT_LENGTH, TEXT)是最基本且普遍存在的列。其他列在较新版本中引入。 示例查询: 要查看当前用户拥有的所有视图的基本信息(名称和定义长度),可以运行: ```sql SELECT view_name, text_length FROM user_views; ``` 要查看特定视图(例如'EMP_VIEW')的完整定义,可以运行: ```sql SELECT text FROM user_views WHERE view_name = 'EMP_VIEW'; -- 注意:视图名称需大写,因为数据字典中存储的是大写名称 ``` 如果视图定义很长,可能需要使用DBMS_METADATA包来获取格式化的DDL语句: ```sql SELECT DBMS_METADATA.GET_DDL('VIEW', 'EMP_VIEW') FROM dual; ``` 引用说明:引用[1]中提到了ALL_VIEWS的列,但USER_VIEWS与其结构基本一致(除了没有OWNER列)。因此,我们可以参考引用[1]中对列的说明[^1]。 相关问题: 1. Oracle中如何查询其他用户创建的视图? 2. 如何获取视图的创建时间? 3. 如何查看视图的依赖关系(即视图基于哪些表或其他视图)? 4. 在Oracle中如何修改视图定义?</think>### Oracle `USER_VIEWS` 视图字段详解 `USER_VIEWS` 是 Oracle 数据字典视图,存储**当前用户拥有的所有视图的定义信息**。以下是其核心字段的详细解释(基于 Oracle 19c 标准): | **字段名** | **数据类型** | **说明** | |--------------------|--------------|--------------------------------------------------------------------------| | **`VIEW_NAME`** | `VARCHAR2(30)` | 视图的名称(**大写存储**,查询时需用 `UPPER('视图名')`) | | **`TEXT_LENGTH`** | `NUMBER` | 视图定义 SQL 语句的字节长度(单位:字节) | | **`TEXT`** | `CLOB` | **视图的完整定义 SQL**(即 `CREATE VIEW` 中的 `SELECT` 语句) | | **`TYPE_TEXT`** | `CLOB` | 类型视图的定义(普通视图此列为空) | | **`OID_TEXT`** | `CLOB` | 对象标识符(OID)子句的定义(普通视图此列为空) | | **`VIEW_TYPE_OWNER`** | `VARCHAR2(30)` | 类型视图的所有者(普通视图此列为空) | | **`VIEW_TYPE`** | `VARCHAR2(30)` | 视图类型标识(如 `OBJECT VIEW`) | | **`SUPERVIEW_NAME`** | `VARCHAR2(30)` | 父视图名称(仅当视图是子视图时有效) | | **`READ_ONLY`** | `VARCHAR2(1)` | 是否只读视图(`Y`/`N`) | | **`EDITIONING_VIEW`** | `VARCHAR2(1)` | 是否为版本化视图(`Y`/`N`,Oracle 12c+) | --- ### 关键字段使用示例 #### 1. **查询视图定义(核心用途)** ```sql SELECT TEXT FROM USER_VIEWS WHERE VIEW_NAME = UPPER('employee_view'); -- 必须大写 ``` 结果返回 `CREATE VIEW` 中的完整 `SELECT` 语句[^1]。 #### 2. **检查视图属性** ```sql SELECT VIEW_NAME, READ_ONLY, TEXT_LENGTH FROM USER_VIEWS WHERE TEXT_LENGTH > 1000; -- 筛选复杂视图 ``` #### 3. **查看所有视图基本信息** ```sql SELECT VIEW_NAME, READ_ONLY, EDITIONING_VIEW FROM USER_VIEWS; ``` --- ### 注意事项 1. **名称大小写** Oracle 数据字典默认以**大写**存储对象名,查询时需用 `UPPER()` 转换: ```sql -- 错误写法(可能无结果) SELECT TEXT FROM USER_VIEWS WHERE VIEW_NAME = 'my_view'; -- 正确写法 SELECT TEXT FROM USER_VIEWS WHERE VIEW_NAME = UPPER('my_view'); ``` 2. **权限要求** - `USER_VIEWS` 仅显示**当前用户拥有的视图**。 - 查看其他用户的视图需用 `ALL_VIEWS`(需有 `SELECT` 权限)或 `DBA_VIEWS`(需 DBA 权限)。 3. **长文本处理** 若视图定义过长(`TEXT_LENGTH > 4000`),`TEXT` 列用 `CLOB` 存储,需用 `DBMS_LOB.SUBSTR()` 分段读取: ```sql SELECT DBMS_LOB.SUBSTR(TEXT, 4000, 1) AS VIEW_DEF FROM USER_VIEWS WHERE VIEW_NAME = UPPER('large_view'); ``` --- ### 与其他视图的关系 | **数据字典视图** | **作用域** | **区别** | |------------------|-------------------------------|-----------------------------------| | `USER_VIEWS` | 当前用户拥有的视图 | 无 `OWNER` 列 | | `ALL_VIEWS` | 当前用户有权限访问的所有视图 | 含 `OWNER` 列(视图所有者)[^1] | | `DBA_VIEWS` | 数据库中所有视图 | 需 DBA 权限,含 `OWNER` 列 | > 引用说明:`USER_VIEWS` 的结构与 `ALL_VIEWS` 基本一致,但过滤了非当前用户的视图[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值