THU.源码解析
序列化类源码分析
ser.is_valid '在进行校验之后,会保存校验信息,,因此即使进行多次校验判断也只执行一次' --> BaseSerializer 的 is_valid --> self._validated_data = self.run_validation(self.initial_data) --> 是哪个类的 run_validation?不是 Field 类的,而是 Serializer 类的
-Serializer 类
-run_validation 内部有一句
-value = self.to_internal_value(data)
for field in fields:
validate_method = getattr(self, 'validate_' + field.field_name, None)
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
validated_value = validate_method(validated_value)
-value = self.validate(value)
请求与响应
DRF 的请求
-.data:包含了对POST、PUT、PATCH请求方式解析后的数据
-.query_params:Django标准的request.GET
- 默认情况支持三种
-全局配置(在项目的settings.py中)
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
]
}
-局部配置(在视图类中写类属性)
class IndexView(APIView):
parser_classes = [JSONParser,]
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
]
响应
-data:要返回的数据,放到了http响应的响应体中
-status:http响应的状态码
-drf把所有的状态码都定义成了常量
-rest_framework.status下
-headers http响应头,是个字典
{'name':'lqz'}
-content_type响应编码格式,了解
-全局配置(在项目的settings.py中)
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
-局部配置(在视图类中写类属性)
class IndexView(APIView):
renderer_classes = [JSONOpenAPIRenderer,]
视图组件之两个视图基类
APIView
class BookView(APIView):
def get(self, request):
qs = Book.objects.all()
ser = serializer.BookSerializer(instance=qs, many=True)
return Response(data=ser.data, status=200)
def post(self, request):
ser = serializer.BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '创建成功'})
else:
return Response(data=ser.errors)
class BookDetailView(APIView):
def get(self, request, pk):
book = Book.objects.all().filter(pk=pk).first()
ser = serializer.BookSerializer(instance=book)
return Response(data=ser.data, status=200)
def put(self, request, pk):
book = Book.objects.all().filter(pk=pk).first()
ser = serializer.BookSerializer(data=request.data, instance=book)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '修改成功'})
else:
return Response(data=ser.errors)
def delete(self, request, pk):
Book.objects.filter(pk=pk).delete()
return Response(data={'code': 100, 'msg': '删除成功'})
GenericAPIView
'''
有两个类属性
queryset = Book.objects.all() # 你要序列化的数据
serializer_class = serializer.BookSerializer # 你要使用的序列化类
三个方法
get_queryset() # 获取要序列化的数据
get_serializer() # 获取要使用的序列化类
get_object() # 获取单条数据(一定要用pk,如果你想改,重写类属性lookup_field)
'''
from rest_framework.generics import GenericAPIView
class BookView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request):
qs = self.get_queryset()
ser = self.get_serializer(instance=qs, many=True)
return Response(data=ser.data, status=200)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '创建成功'})
else:
return Response(data=ser.errors)
class BookDetailView(GenericAPIView):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request, *args, **kwargs):
book = self.get_object()
ser = self.get_serializer(instance=book)
return Response(data=ser.data, status=200)
def put(self, request, pk):
book = self.get_object()
ser = self.get_serializer(data=request.data, instance=book)
if ser.is_valid():
ser.save()
return Response(data={'code': 100, 'msg': '修改成功'})
else:
return Response(data=ser.errors)
def delete(self, request, pk):
self.get_object().delete()
return Response(data={'code': 100, 'msg': '删除成功'})
视图组件之5个视图扩展类
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
from rest_framework.generics import GenericAPIView
class BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class BookDetailView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
视图组件之9个视图子类
from rest_framework.generics import ListAPIView, CreateAPIView, ListCreateAPIView
from rest_framework.generics import RetrieveAPIView, UpdateAPIView, DestroyAPIView, RetrieveUpdateAPIView, RetrieveDestroyAPIView, RetrieveUpdateDestroyAPIView
class BookView(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
class BookDetailView(RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
视图组件之视图集
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = serializer.BookSerializer
ViewSetMixin类源码分析,as_view()
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
def view(request, *args, **kwargs):
for method, action in actions.items():
handler = getattr(self, action)
setattr(self, method, handler)
return csrf_exempt(view)