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)

 

Rest Framework(1):FBV和CBV

上一篇:LVS+Keepalived高可用群集


下一篇:IDEA创建Servlet