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

 

 

 

 

posted @ 2022-09-29 18:31  stephen_hao  阅读(45)  评论(0编辑  收藏  举报