TUE.序列化组件的简单应用
CBV源码分析
我们在路由中写了 IndexView.as_view() --> 实际上放了一个函数内存地址,源码是 --> 实际上是 view 的内存地址
@classonlymethod
def view(request, *args, **kwargs):
return self.dispatch(request, *args, **kwargs)
return view
当请求来了,跟路由匹配成功,就会执行 view(request)
内部执行了 self.dispatch(request, *args, **kwargs)
def dispatch(self, request, *args, **kwargs):
'get' in [请求方式列表]
if request.method.lower() in self.http_method_names:
通过反射去对象中拿 get 方法
handler 就是 get 这个方法
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
最终执行了 handler(request, *args, **kwargs)
-如果是 get 请求,相当于执行了视图类中的 get 方法
DRF 之 APIView 执行流程分析
请求来了,由于会 APIView 中定义了 as_view 方法,且继承了 APIView ,因此会执行 views.BookView.as_view()(request) --> 触发 APIView 的 as_view
@classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs)
return csrf_exempt(view)
假设 get 请求来了,执行 view() -- 最重要的 --> self.dispatch() --> APIView 的
def dispatch(self, request, *args, **kwargs):
request = self.initialize_request(request, *args, **kwargs)
try:
self.initial(request, *args, **kwargs)
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
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
return self.response
apiview:干了三件事
-把老的request对象包装成了新的request对象
-通过 APIView 的 initialize_request,包装的
-以后再在视图类中用的request对象,都是新的
-在执行视图类中的方法之前,执行了三大认证
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
-处理全局异常
只要继承了APIView,以后用的request对象,就是drf的request对象了
在执行视图类的方法之前,会先执行三大认证,如果有异常,会被捕获并处理
DRF 之 Request 对象
-老的django的request在drf的request._request中
-新的request用起来跟原来一模一样用,没有一点区别
-对象.属性,会触发类的 __getattr__方法
-重写了__getattr__
return getattr(self._request, attr)
-新的request多个一个data属性--》所有post提交的数据,都放在它中
-类中,某种特定条件就会触发它执行的方法
-__init__, __str__
__getattr__(self, item) 对象调用属性不存在的时候触发
__setattr__(self, key, value) 对象给属性赋值的时候触发
1、self.__dict__[key]=value
2、objects.__setattr__(self, key, value)
序列化组件之 Serializer 的使用
序列化类可以快速地吧 Queryset 对象转化成列表或字典
借助实现序列化类实现序列化
class BookSerializer(serializers.Serializer):
title = serializers.CharField(max_length=32)
price = serializers.IntegerField()
class More(APIView):
@staticmethod
def get(request):
book_list = Books.objects.all()
ser = BookSerializer(instance=book_list, many=True)
return Response(ser.data)
补充
- 当 JsonResponse 返回的是列表时,需要修改第二个参数
safe=false
def path(func)
def inner(*args, **kwargs)
res = func(*args, **kwargs)
return res
return
@auth
def test():
print('Python')
等价于
test = auth(test)