• Rest Framework(1):FBV和CBV


    FBV的意思是function base view,意思就是在views.py中写函数。我们常用的urls.py里面的路径对应views里面的函数。

    CBV的意思是class base view,意思就是在views.py中写类,urls.py里面的路径对应一个类。

    1. 列表生成式:

    class Foo:
        pass
    
    class Bar:
        pass
    
    v = []
    for i in [Foo,Bar]:
        obj = i()
        v.append(obj)
    
    v = [item() for item in [Foo,Bar]]  # v是一个实例化对象列表

    2. 面向对象

    封装:

    a. 对同一类方法封装到类中(文件增删改查方法,数据库的增删改查方法 )

    b. 将数据封装到对象中

    class File:
        def __init__(self,a1,a2):
            self.a1 = a1 
            self.xxx = a2
        def get:...
        def delete:...
        def update:...
        def add:...
    
    obj1 = File(123,666)
    obj2 = File(456,999)

    扩展:

    class Request(object):
        def __init__(self,obj):
            self.obj = obj
    
        @property
        def user(self):
            return self.obj.authticate()
    
    class Auth(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def authticate(self):
            return self.name
    
    
    class APIView(object):
    
        def dispatch(self):
            self.f2()
    
        def f2(self):
            a = Auth('alex',18)
            req = Request(a)
            print(req.user)
    
    obj = APIView()
    obj.dispatch()  # 打印alex

    3. CBV基于反射实现根据请求方式的不同,执行不同的方法,方法包括:

    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']

    原理:url --> view方法 --> dispatch方法

    views.py

    # 如下是FBV在视图文件中写函数
    def users(request):
        user_list = ['alex','oldboy']
        return HttpResponse(json.dumps((user_list)))
    
    # 如下是CBV在视图文件中写类,需要注意类必须继承View这个父类。同时类名按照规范要以View结尾。
    from django.views import View
    
    class StudentsView(View):
    
        def get(self,request,*args,**kwargs):
            return HttpResponse('GET')
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')
    
        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')
    
        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')

    urls.py

    re_path('^students/', views.StudentsView.as_view()),

    如上程序执行逻辑首先用户通过url访问到路径students/,触发视图函数views中StudentsView类的as_view()方法,但是我们看到该StudentsView没有as_view()方法,于是去他的父类View找。

    def as_view(cls, **initkwargs):
       # 省略前面的判断过程
        def view(request, *args, **kwargs):
            # 省略前面的判断过程
            return self.dispatch(request, *args, **kwargs)
        return view
    # 可以看到该函数调用的是dispath函数

    于是我们继续找到dispatch函数:

    def dispatch(self, request, *args, **kwargs):
           # http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] 
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),                                                      self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
    # 如果request.method.lower()在http_method_names中,则执行下面的handler,去获取request方法,若是没有获取到就调用http_method_not_allowed抛出异常。如是获取到了就返回这个方法函数。例如:
    # post(request, *args, **kwargs) get(request, *args, **kwargs),注意都是小写,因为用了lower关键字,将方法编程了小写。
    # 若是在执行handler函数前后加一些动作,则可以完成例如用户认证,或者限流等操作。
    # 所以接下来我们尝试改写dispatch函数。

    改写dispatch函数,由于dispatch函数在父类中,我们在当前类中写一个相同的dispatch函数将被优先调用。

    class StudentsView(View):
        def dispatch(self, request, *args, **kwargs):
            print('before')  # 在请求处理之前可以进行的操作,例如可以做认证等
            ret = super(StudentsView,self).dispatch(request, *args, **kwargs)
            print('after')  # 在请求处理之后可以进行的操作,可以添加访问记录,用来做限流
            return ret
    
        def get(self,request,*args,**kwargs):
            return HttpResponse('GET')
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')
    
        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')
    
        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')

    考虑上面的类,若要在处理请求前后做操作,需要在每一个类里面去改写这个dispatch函数,于是可以将该函数写在一个类中,通过继承来完成这个操作。

    继承(多个类共用的功能,为了避免重复编写):

    from django.views import View
    
    class MyBaseView(object):
        def dispatch(self, request, *args, **kwargs):
            print('before')
            ret = super(MyBaseView,self).dispatch(request, *args, **kwargs)
            print('after')
            return ret
    
    class StudentsView(MyBaseView,View):  # 注意要把自己写的父类写在前面,前面的优先
    
        def get(self,request,*args,**kwargs):
            print('get方法')
            return HttpResponse('GET')
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')
    
        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')
    
        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')
    
    class TeachersView(MyBaseView,View):
    
        def get(self,request,*args,**kwargs):
            return HttpResponse('GET')
    
        def post(self, request, *args, **kwargs):
            return HttpResponse('POST')
    
        def put(self, request, *args, **kwargs):
            return HttpResponse('PUT')
    
        def delete(self, request, *args, **kwargs):
            return HttpResponse('DELETE')
  • 相关阅读:
    创建可按比例调整的布局的 Windows 窗体
    Visual C# 2010 实现资源管理器
    Visual C# 2010 实现菜单项和状态栏
    使用异步事件在后台进行计算并报告进度
    A Byte of Python(简明Python教程) for Python 3.0 下载
    面向对象思想
    封装变化(二)
    好玩,看你的博客价值几何?
    基于消息与.Net Remoting的分布式处理架构
    设计之道
  • 原文地址:https://www.cnblogs.com/tortoise512/p/15177566.html
Copyright © 2020-2023  润新知