zoukankan      html  css  js  c++  java
  • FBV与CBV

    FBV与CBV

      视图函数并不只是指函数也可以是类。FBV(基于函数的视图) 面向函数式编程。CBV(基于类的视图) 面向对象式编程

    问题:基于CBV的视图函数,get请求来就会走类里面get方法,post请求来就会走类里面post方法 为什么???

    urls.py中
    url(r'^login/',views.MyLogin.as_view())
    views.py中
    from django.views import View
    
    class MyLogin(View):
    def get(self,request):
    print("from MyLogin get方法")
    return render(request,'login.html')
    def post(self,request):
    return HttpResponse("from MyLogin post方法")

    研究方向 

    1.从url入手
    url(r'^login/',views.MyLogin.as_view()) 由于函数名加括号执行优先级最高,所以这一句话一写完会立刻执行as_view()方法
    
    @classonlymethod
    def as_view(cls, **initkwargs): # cls就是我们自己的写的类 MyLogin
    def view(request, *args, **kwargs):
    self = cls(**initkwargs) # 实例化产生MyLogin的对象 self = MyLogin(**ininkwargs)
    if hasattr(self, 'get') and not hasattr(self, 'head'):
    self.head = self.get
    self.request = request
    self.args = args
    self.kwargs = kwargs
    # 上面的几句话都仅仅是在给对象新增属性
    return self.dispatch(request, *args, **kwargs) # dispatch返回什么 浏览器就会收到什么
    # 对象在查找属性或者方法的时候 你一定要默念 先从对象自己这里找 然后从产生对象的类里面找 最后类的父类依次往后
    return view
    
    通过源码发现url匹配关系可以变形成
    url(r'^login/',views.view) # FBV和CBV在路由匹配上是一致的 都是url后面跟函数的内存地址
    2.当浏览器中输入login 会立刻触发view函数的运行
    def dispatch(self, request, *args, **kwargs):
    # Try to dispatch to the right method; if a method doesn't exist,
    # defer to the error handler. Also defer to the error handler if the
    # request method isn't on the approved list.
    # 我们先以GET为例
    if request.method.lower() in self.http_method_names: # 判断当前请求方法是否在默认的八个方法内
    # 反射获取我们自己写的类产生的对象的属性或者方法
    # 以GET为例 handler = getattr(self,'get','取不到报错的信息')
    # handler = get(request)
    handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
    else:
    handler = self.http_method_not_allowed
    return handler(request, *args, **kwargs) # 直接调用我们自己的写类里面的get方法
    # 源码中先通过判断请求方式是否符合默认的八个请求方法 然后通过反射获取到自定义类中的对应的方法执行

     CBV可以按照下面截图的顺序去理解。

     

    Django源码

    前提:

    1.django除了暴露给用户一个settings.py配置文件之外 自己内部还有一个全局的配置文件

    2.我们在使用配置文件的时候 可以直接直接导入暴露给用户的settings.py也可以使用django全局的配置文件 并且后者居多

    from django.conf import settings

    3.django的启动入口是manage.py

    自定义一个Django源码

    import
    os import sys if __name__ == "__main__": # django在启动的时候 就会往全局的大字典中设置一个键值对 值是暴露给用户的配置文件的路径字符串 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings") class Settings(object): def __init__(self, settings_module): # settings_module = 'day54.settings' # update this dict from global settings (but only for ALL_CAPS settings) for setting in dir(global_settings): # django全局配置文件 # dir获取django全局配置文件中所有的变量名 if setting.isupper(): # 判断文件中的变量名是否是大写 如果是大写才会执行/生效 setattr(self, setting, getattr(global_settings, setting)) # 给settings对象设置键值对 # 给settings对象设置键值对 settings[配置文件中大写的变量名] = 配置文件中大写的变量名所对应的值 # store the settings module in case someone later cares self.SETTINGS_MODULE = settings_module # 'day54.settings' mod = importlib.import_module(self.SETTINGS_MODULE) # mod = 模块settings(暴露给用户的配置文件) for setting in dir(mod): # for循环获取暴露给用户的配置文件中所有的变量名 if setting.isupper(): # 判断变量名是否是大写 setting_value = getattr(mod, setting) # 获取大写的变量名所对应的值 setattr(self, setting, setting_value) # 给settings对象设置键值对 """ d = {} d['username'] = 'jason',d['username'] = 'egon' 用户如果配置了就用用户的,用户如果没有配置就用系统默认的 其实本质就是利用字典的键存在就是替换的原理,实现了用户配置就用用户的用户没配置就用默认的 """

    class LazySettings(LazyObject): def _setup(self, name=None): # os.environ你可以把它看成是一个全局的大字典 settings_module = os.environ.get(ENVIRONMENT_VARIABLE) # 从大字典中取值键为DJANGO_SETTINGS_MODULE所对应的值:day54.settings # settings_module = 'day54.settings' self._wrapped = Settings(settings_module) # Settings('day54.settings') settings = LazySettings() # 单例模式

  • 相关阅读:
    Nodejs读取文件时相对路径的正确写法(使用fs模块)
    node 读取多个文件、合并多个文件、读写多个文件
    js中typeof用法详细介绍
    express源码分析之Router
    14 Django的用户认证组件
    13-1 jquery操作cookie
    13 Django组件- cookie与session
    12 Django组件-form组件
    11 Django组件-分页器
    10 Django与Ajax
  • 原文地址:https://www.cnblogs.com/blue-tea/p/11546675.html
Copyright © 2011-2022 走看看