drf之视图组件

drf请求与响应

1.request请求 :通过http请求,经过OSI协议,拿着前端提供的数据给了django,django把请求给了request的对象,drf又对request进行了一次封装,每次请求都是一个新的request对象,,所以request能够直接点data获取数据

http版本0.9
http1.1  现在基本都是用的这个版本  一个请求通道可以建立多次请求,不断开链接,当不再需要数据传输的时候才会断开连接
http2.0 多路复用 一次发送多条数据 一个请求通道 打包发送 接收
2.Request类的属性和方法
data 可以直接用request.data获取三种编码格式的数据 数据获取出来的是字典 通过Response变成字符串类型返回给前端
# 原生django中的put提交的数据在request.post中提取不了
query_params 相当于django中的request.post 底层原理也是用__getattr__方法
3.Response类 
主要的三个方法: 
 1.data=None 字典或者列表序列化成json格式字符串 返回给前端放在http响应的body中
 2.status=None 状态码 可以直接写,也可用导入封装好的http响应状态码 导入模块即可  默认是200
 3..headers=None  http的响应头 以字典的k:v形式展示   # 可以自定义响应头 
 
 4.template_name=None  在浏览器中看到好看的页面 有指定的模板也可以不加
 5.content_type=None  响应的编码格式 默认是json类型
drf能够解析的请求编码格式
# 默认能够解析:urlencoded,form-data,json
drf中的配置文件settings.py中有(默认的解析)DEFAULT_PARSER_CLASSES:
  -'rest_framework.parsers.JSONParser', 可以解析json格式
  -'rest_framework.parsers.FormParser', 可以解析urlencoded格式
  -'rest_framework.parsers.MultiPartParser' 可以解析form-data格式
可以通过配置修改编码格式或者指定编码格式:
方式1:全局配置 在settings写:以上默认编码格式 不需要的直接注释掉
方式2:局部配置 在自己写的视图类中写:
class TestView(APIView):parser_classes = [JSONParser,FormParser,MultiPartParser]
总结
总结: 解析类的使用顺序:优先使用视图类自己的,然后是项目配置文件的,最后是内置文件的
实际在项目中基本都是使用JSONParser,FormParser
如果上传文件的话,只允许使用MultiPartParser
格式使用越少越能减少出错的概率
响应编码
默认情况下,响应编码是根据客户端类型决定的
分为全局配置:
   REST_FRAMEWORK = {
       'DEFAULT_RENDERER_CLASSES': [
            # 'rest_framework.renderers.JSONRenderer', # json格式
            'rest_framework.renderers.BrowsableAPIRenderer', #浏览器的格式]}
局部配置: 在视图类中配置
 class TestView(APIView):renderer_classes = [JSONRenderer]      

drf视图组件

视图基类 :APIView和GenericAPIView
# 基于这个写的五个接口 封装的五个方法
基于APIView写五个接口
class BookView(APIView):
    def get(self,request):
        book_list = Book.objects.all()
        ser = BookSerializers(instance=book_list,many=True)
        return Response(ser.data)
#

class BookView(APIView):
    def get(self,request,pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializers(instance=book)
        return Response(ser.data)


class BookView(APIView):
    def post(self,request):
        ser = BookSerializers(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors)

class BookView(APIView):
    def put(self,request,pk):
        book = Book.objects.filter(pk=pk).first()
        ser = BookSerializers(instance=book,data=request)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors)

class BookView(APIView):
    def delete(self,request,pk):
        Book.objects.filter(pk=pk).delete()
        return Response('')


基于GenericAPIView写五个接口
class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializers

    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(ser.data)
        else:
            return Response(ser.errors)


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializers

    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(ser.data)
        return Response(ser.errors)

    def delete(self, request, pk):
        self.get_queryset().filter(pk=pk).delete()
        return Response()

基于面向对象封装

单方法封装
class Once():  #查询一条数据
    def get(self, request, pk):
        book = self.get_object()
        ser = self.get_serializer(instance=book)
        return Response(ser.data)

class More():  # 查询多条数据
    def get(self, request):
        book_list = self.get_queryset()
        ser = self.get_serializer(instance=book_list, many=True)
        return Response(ser.data)

class Amend():  # 修改数据
    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(ser.data)
        else:
            return Response(ser.errors)

class Add():  # 添加数据
    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors)
 
class Dle():  # 删除数据
    def delete(self, request, pk):
        self.get_queryset().filter(pk=pk).delete()
        return Response('')

基于单方法组合封装
class MoreAdd(GenericAPIView, More, Add):
    def __init__(self):
        super(More, self).__init__()  # 查询多条数据
        super(Add, self).__init__()  # 添加数据

class OnceDleAmend(GenericAPIView, Once, Dle, Amend):
    def __init__(self):
        super(Once, self).__init__()  # 查询一条
        super(Dle, self).__init__()  # 删除一条
        super(Amend, self).__init__()  # 修改一条

class DelAmend(GenericAPIView, Dle, Amend):
    def __init__(self):
        super(Dle, self).__init__()  # 删除一条
        super(Amend, self).__init__()  # 修改一条

class CheckDle(GenericAPIView, Once, Dle):
    def __init__(self):
        super(Dle, self).__init__()  # 删除一条
        super(Once, self).__init__()  # 查询一条

class AmendCheck(GenericAPIView, Amend, Once):
    def __init__(self):
        super(Amend, self).__init__()  # 修改一条
        super(Once, self).__init__()  # 查询一条

组合封装的查询
class BookView(MoreAdd):
    queryset = Book.objects.all()
    serializer_class = BookSerializers

    def __init__(self):
        super(MoreAdd, self).__init__()  # 查询多条数据/添加数据


class BookDetailView(OnceDleAmend):
    queryset = Book.objects.all()
    serializer_class = BookSerializers

    def __init__(self):
        super(OnceDleAmend, self).__init__()  # 修改数据/查询一条/删除数据

posted @ 2022-09-29 21:31  Hsummer  阅读(20)  评论(0编辑  收藏  举报