drf接口

1、请求与响应

​ drf框架中,前后端之间的请求:request以及响应:response

1.1、请求

​ 请求对象可以通过查看类得到Request可以继承request,并且Request是二次封装request,将原生request作为drf request对象的_request 属性

​ 请求对象.data:前端以三种编码方式传入的数据,都可以取出来

​ 请求对象.query_params 与Django里面的request.GET相同

from rest_framework.request import Request

1.2、响应

​ data(数据,以字典形式)和status(状态码,默认为200)默认为false,需要返回前端数据时,可以设置数据

​ 所有的状态码都放置在 from rest_framework import status 路径下,并且定义了常量的状态

from rest_framework.response import Response
def __init__(self, data=None, status=None,	#源代码
                 template_name=None, headers=None,
                 exception=False, content_type=None):

1.3、响应格式

​ 浏览器响应是浏览器的格式,postman响应是json格式可以通过配置实现,但返回的都是json格式。

​ drf默认配置文件的查询顺序为:项目的setting===》drf默认配置文件

​ drf默认配置信息的查询顺序为:自己类中=》项目的setting=》默认信息

1.4、设置响应格式的配置信息

​ 1.局部使用:

​ 在需要更改配置信息的视图下添加信息,将其设置成json格式,浏览器默认浏览器格式,需要在浏览器中显示

from rest_framework.renderers import JSONRenderer
renderer_classes = [JSONRenderer,]

​ 2.全局使用:

​ 在setting中添加,所有的请求都有效

REST_FRAMEWORK = {
   'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
   'rest_framework.renderers.JSONRenderer',  # json渲染器
   'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
            )
        }

2、drf提供的视图

2.1、drf视图的作用

​ drf中的视图主要提供的作用为:

​ 1.控制序列化器来检验、保存、转换数据

​ 2.控制数据库查询的功能

2.2、drf的视图基类

​ rest_framework提供了众多的视图基类以及扩展类来简化代码

​ 这里先介绍APIView和GenericAPIView两种视图基类

2.3、基于APIView写接口

#### views.py
from rest_framework.generics import GenericAPIView
from app01.models import Book
from app01.ser import BookSerializer
# 基于APIView写的
class BookView(APIView):
    def get(self,request):
        book_list=Book.objects.all()
        book_ser=BookSerializer(book_list,many=True)

        return Response(book_ser.data)
    def post(self,request):
        book_ser = BookSerializer(data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status':101,'msg':'校验失败'})


class BookDetailView(APIView):
    def get(self, request,pk):
        book = Book.objects.all().filter(pk=pk).first()
        book_ser = BookSerializer(book)
        return Response(book_ser.data)

    def put(self, request,pk):
        book = Book.objects.all().filter(pk=pk).first()
        book_ser = BookSerializer(instance=book,data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status': 101, 'msg': '校验失败'})

    def delete(self,request,pk):
        ret=Book.objects.filter(pk=pk).delete()
        return Response({'status': 100, 'msg': '删除成功'})
    
#models.py
class Book(models.Model):
    name=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=5,decimal_places=2)
    publish=models.CharField(max_length=32)
#ser.py
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model=Book
        fields='__all__'
# urls.py
path('books/', views.BookView.as_view()),
re_path('books/(?P<pk>\d+)', views.BookDetailView.as_view()),

2.4、基于GenericAPIView写的接口

# views.py
class Book2View(GenericAPIView):
    #queryset要传queryset对象,查询了所有的图书
    # serializer_class使用哪个序列化类来序列化这堆数据
    queryset=Book.objects
    # queryset=Book.objects.all()
    serializer_class = BookSerializer
    def get(self,request):
        book_list=self.get_queryset()
        book_ser=self.get_serializer(book_list,many=True)

        return Response(book_ser.data)
    def post(self,request):
        book_ser = self.get_serializer(data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status':101,'msg':'校验失败'})


class Book2DetailView(GenericAPIView):
    queryset = Book.objects
    serializer_class = BookSerializer
    def get(self, request,pk):
        book = self.get_object()
        book_ser = self.get_serializer(book)
        return Response(book_ser.data)

    def put(self, request,pk):
        book = self.get_object()
        book_ser = self.get_serializer(instance=book,data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status': 101, 'msg': '校验失败'})

    def delete(self,request,pk):
        ret=self.get_object().delete()
        return Response({'status': 100, 'msg': '删除成功'})
    
 #url.py
    # 使用GenericAPIView重写的
    path('books2/', views.Book2View.as_view()),
    re_path('books2/(?P<pk>\d+)', views.Book2DetailView.as_view()),

2.5、基于GenericAPIView和5个视图扩展类写的接口

from rest_framework.mixins import  ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
# views.py
class Book3View(GenericAPIView,ListModelMixin,CreateModelMixin):

    queryset=Book.objects
    serializer_class = BookSerializer
    def get(self,request):
        return self.list(request)

    def post(self,request):
        return self.create(request)

class Book3DetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):
    queryset = Book.objects
    serializer_class = BookSerializer
    def get(self, request,pk):
        return self.retrieve(request,pk)

    def put(self, request,pk):
        return self.update(request,pk)

    def delete(self,request,pk):
        return self.destroy(request,pk)
# urls.py
    # 使用GenericAPIView+5 个视图扩展类  重写的
    path('books3/', views.Book3View.as_view()),
    re_path('books3/(?P<pk>\d+)', views.Book3DetailView.as_view()),

2.6、使用ModelViewSet编写5个接口

# views.py
from rest_framework.viewsets import ModelViewSet
class Book5View(ModelViewSet):  #5个接口都有,但是路由有点问题
    queryset = Book.objects
    serializer_class = BookSerializer
    
# urls.py
# 使用ModelViewSet编写5个接口
    path('books5/', views.Book5View.as_view(actions={'get':'list','post':'create'})), #当路径匹配,又是get请求,会执行Book5View的list方法
    re_path('books5/(?P<pk>\d+)', views.Book5View.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),


2.7、源码分析ViewSetMixin

# 重写了as_view
# 核心代码(所以路由中只要配置了对应关系,比如{'get':'list'}),当get请求来,就会执行list方法
for method, action in actions.items():
    #method:get
    # action:list
    handler = getattr(self, action)
    #执行完上一句,handler就变成了list的内存地址
    setattr(self, method, handler)
    #执行完上一句  对象.get=list
    #for循环执行完毕 对象.get:对着list   对象.post:对着create


2.8、继承ViewSetMixin的视图类

# views.py
from rest_framework.viewsets import ViewSetMixin
class Book6View(ViewSetMixin,APIView): #一定要放在APIVIew前
    def get_all_book(self,request):
        print("xxxx")
        book_list = Book.objects.all()
        book_ser = BookSerializer(book_list, many=True)
        return Response(book_ser.data)
    
# urls.py
    #继承ViewSetMixin的视图类,路由可以改写成这样
    path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),

posted @ 2020-07-09 22:50  疏星淡月  阅读(289)  评论(0编辑  收藏  举报