drf之试图基类
一、请求与响应
# 现在我们在写视图类的时候都是继承了APIView # 而APIView的request都变成了新的request了跟继承了View的request已经不一样了 # 所以每次请求都是一个新的request #Request类的属性和方法 -data: 中有POST,PUT,PATCH请求方式解析过后的数据 -django原生的 put提交的数据 request.body中是提取不出来的 -query_params: 就是GET请求 其他的用法还是跟以前一样 文件数据还是在request.FILES中获取 (method,path)也是一样的用法 ---》底层原理就是用来反射 getattr # Response类 Response中有这几个方法: data=None, # 就是后端传给前端的数据 字典和列表---》序列化成json格式的字符串传个前端(数据放在了http响应的body中了) status=None, # http的 响应状态码 默认是 200 -drf帮我们把所有的响应状态码都做成了常量,我们可以直接导入使用 from rest_framework.status import HTTP_200_OK headers=None, # http的响应头, 字典{} 因为响应头就是一堆的K:V键值对 template_name=None, # 可以指定模板 这样就可以在浏览器中看到好看的页面 content_type=None # 响应的编码格式(json) # 我们还可以在响应头中添加数据 class GetView(GenericAPIView): def get(self, request): return Response(headers={'name': 'jason'}) # 直接在headers中使用字典添加 # 而原生django想要在响应头中添加数据需要这样写: res=JsonResponse(d) res['rrr'] = 'yyyy' return res
二、drf能够解析的请求编码,想要编码
1.请求编码
# drf默认能够解析的编码 urlencoded form-data json # 我们可以通过配置完成:项目中没有配置,是在drf内置的配置文件配置好的 -drf也是有两套,一套是项目中得配置(settings.py),一套是默认的配置 -drf的配置文件settings.py中有 DEFAULT_PARSER_CLASSES(默认的解析类) 已经配置好了三个默认的解析格式 -'rest_framework.parsers.JSONParser', 可以解析json格式 -'rest_framework.parsers.FormParser', 可以解析urlencoded格式 -'rest_framework.parsers.MultiPartParser' 可以解析form-data格式 # -想让我们的接口只能接受json格式 -方式一:全局配置---》项目配置文件---》以后所有的接口都遵循这个配置 REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', # 'rest_framework.parsers.FormParser', # 'rest_framework.parsers.MultiPartParser', ], } # 不想用哪个解析格式 那么只需要把这个解析格式注释即可 # -方式二:局部配置 from rest_framework.parsers import JSONParser, MultiPartParser, FormParser class BookView(APIView): parser_classes = [JSONParser, ] # 总结 解析类的使用顺序 ---》会先找本身视图类的 ---》再找项目的配置文件 ---》最后找drf的配置文件 -实际项目如何配置 -基本上都运行JSONParser,FormParser -如果上传文件只允许MultiPartParser
2.响应编码
# 如果用浏览器 那么就是好看的页面 如果使用postman那么就是json格式 -默认情况下,响应的编码格式是根据客户端类型决定的 # drf有默认配好了 响应的编码格式 # 全局配置:在项目的配置文件 REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ # 'rest_framework.renderers.JSONRenderer', # json格式 'rest_framework.renderers.BrowsableAPIRenderer', #浏览器的格式 ] } # 局部配置 from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer class BookView(APIView): renderer_classes = [JSONRenderer, BrowsableAPIRenderer] # 使用顺序: 视图类---》项目的配置文件 ---》drf的配置文件
三、两个试图基类
# APIView # GenericAPIView ---》 其实也是继承了APIView了 # 类属性 queryset = User.objects.all() serializer_class = BookSerializer # 方法: self.get_queryset() # 获取所有需要序列化的数据 self.get_objects() # 根据pk获取单个数据 self.get_serializer() # 获取要使用的序列化类
3.1基于APIView写五个接口
class UserView(APIView): def get(self, request): book_list = User.objects.all() ser = UserSerializer(instance=book_list, many=True) return Response(ser.data) def post(self, request): ser = UserSerializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "新增成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) class UserDetailView(APIView): def get(self, request, pk): book = User.objects.filter(pk=pk).first() ser = UserSerializer(instance=book) return Response(ser.data) def put(self, request, pk): book = User.objects.filter(pk=pk).first() ser = UserSerializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "修改成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): User.objects.filter(pk=pk).delete() return Response('') # 我们会发现代码有点冗余了
3.2使用GenericApiView写五个接口
from rest_framework.generics import GenericAPIView class UserView(GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def get(self, request): book_list = self.get_queryset() ser = self.get_serializer(instance=book_list, many=True) return Response(ser.data) def post(self, request): ser = self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "新增成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) class UserDetailView(GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def get(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book) return Response(ser.data) def put(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': "修改成功"}, status=201) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response('') # 这个时候我们写单表的五个接口其实都是差不多的 所以我们如果还要写其他表的五个接口 那么我们只需要把下面的参数该了即可 后面的五个接口都不需要动了 queryset = User.objects.all() serializer_class = UserSerializer
四、作业
1.使用GenericAPIView 写五个接口
view
class BookView(GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer def get(self, request): book_list = self.get_queryset() ser = self.get_serializer(instance=book_list, many=True) return Response(ser.data) def post(self, request): ser = self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '新增成功'}) else: return Response({'code': 101, 'msg': ser.errors}) class BookDetail(GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer def get(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book) return Response(ser.data) def put(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '修改成功'}) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response({})
序列化类
from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
urls
path('books/', views.BookView.as_view()), path('books/<int:pk>', views.BookDetail.as_view()),
2 使用面向对象,写5个父类, 继承GenericAPIView+某几个父类后,就有某几个接口
# 获取全部 class GetView(GenericAPIView): def get(self, request): book_list = self.get_queryset() ser = self.get_serializer(instance=book_list, many=True) return Response(ser.data) # 新增一个 class CreateView(GenericAPIView): def post(self, request): ser = self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '新增成功'}) else: return Response({'code': 101, 'msg': ser.errors}) # 获取一个 class GetOneView(GenericAPIView): def get(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book) return Response(ser.data) # 修改 class UpdateView(GenericAPIView): def put(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '修改成功'}) else: return Response({'code': 101, 'msg': ser.errors}) # 删除一个 class DeleteView(GenericAPIView): def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response({})
2.1 视图类
# 继承了 获取全部的类 class BookView(GetView, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer # 继承了 新增一个的类 class BookView(CreateView, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer # 继承了获取一个的类 class BookView(GetOneView, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer # 继承了 修改类 class BookView(UpdateView, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer # 继承了删除一个的类 class BookView(DeleteView, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer
3 9个视图子类
# 获取全部 class GetView(GenericAPIView): def get(self, request): book_list = self.get_queryset() ser = self.get_serializer(instance=book_list, many=True) return Response(ser.data, headers={'name': 'jason'}) # 新增一个 class CreateView(GenericAPIView): def post(self, request): ser = self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '新增成功'}) else: return Response({'code': 102, 'msg': ser.errors}) # 获取一个 class GetOneView(GenericAPIView): def get(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book) return Response(ser.data) # 修改 class UpdateView(GenericAPIView): def put(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '修改成功'}) else: return Response({'code': 101, 'msg': ser.errors}) # 删除一个 class DeleteView(GenericAPIView): def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response({}) # 获取全部和新增一个 class GetCreateView(GenericAPIView): def get(self, request): book_list = self.get_queryset() ser = self.get_serializer(instance=book_list, many=True) return Response(ser.data) def post(self, request): ser = self.get_serializer(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '新增成功'}) else: return Response({'code': 101, 'msg': ser.errors}) # 获取一个和修改一个 class GetOneUpdateView(GenericAPIView): def get(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book) return Response(ser.data) def put(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '修改成功'}) else: return Response({'code': 101, 'msg': ser.errors}) # 修改一个和删除一个 class UpdateDeleteView(GenericAPIView): def put(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '修改成功'}) else: return Response({'code': 101, 'msg': ser.errors}) def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response({}) # 获取一个和删除一个 class GetOneDeleteView(GenericAPIView): def get(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book) return Response(ser.data) def delete(self, request, pk): self.get_queryset().filter(pk=pk).delete() return Response({})
# 试图类 class BookView(GetOneDeleteView, GenericAPIView): queryset = Book.objects.all() serializer_class = BookSerializer