首页 > 其他分享 >DRF - 视图组件

DRF - 视图组件

时间:2023-02-06 21:24:47浏览次数:37  
标签:ser get self request 视图 组件 class DRF

视图组件


drf的视图,视图类学过APIView

drf的基类,drf提供的最顶层的类

70061675672727_.pic_hd

0、APIView与Django原生的View类的区别

1.APIView中传入视图方法中的Request对象

是REST framework的Request对象

而不是Django的HttpRequest对象

2.视图方法可以返回REST framework的Response对象(使用的是drf的Response对象)

3.任何APIException异常都会被捕获到,并且处理成合适的响应信息

4.在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制

1、两个视图基类

0.APIView类的属性

APIView类属性名称 作用
renderer_classes 响应格式
parser_classes 能够解析的请求格式
authentication_classes 认证类
throttle_classes 频率类
permission_classes 权限类

1.视图基类:APIView

APIView+ModelSerializer+Resposne写5个接口

(1)视图基于APIView + Response

class BookView(APIView):
    def get(self, request):
        books = Book.objects.all()
        ser = BookSerializer(instance=books, many=True)
        return Response(ser.data)

    def post(self, request):

        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            # 咱们只有ser序列化类的对象,但是咱们想要的是新增的数据对象,然后序列化成字典。
            # 但是,大前提是序列化类中新增的create方法一定要返回新增的对象,
            # 虽然我们没有写create方法,但是在ModelSerializer类中create方法,返回了新增了数据对象
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(APIView):
    # 查询单条
    def get(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books)
        return Response(ser.data)

    # 修改
    def put(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    # 删除
    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

(2)序列化类 基于ModelSerializer

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'author_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }

(3)路由

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]

2.视图基类GenericAPIView

GenericAPIView继承了APIView有很多新的属性和方法

(1)视图类中基于 GenericAPIView 来写接口

class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        # 如果通过get_queryset我们可以重写,扩展性更高
        objs = self.get_queryset()
        # 可以通过重写get_serializer_class来控制哪个序列化类来做序列化
        ser = self.get_serializer(instance=objs, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            # 咱们只有ser序列化类的对象,但是咱们想要的是新增的数据对象,然后序列化成字典。
            # 但是,大前提是序列化类中新增的create方法一定要返回新增的对象,
            # 虽然我们没有写create方法,但是在ModelSerializer类中create方法,返回了新增了数据对象
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 查询单条
    def get(self, request, pk):
        books = self.get_object()
        ser = BookSerializer(instance=books)
        return Response(ser.data)

    # 修改
    def put(self, request, pk):
        books = self.get_object()
        ser = self.get_serializer(instance=books, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    # 删除
    def delete(self, request, pk):
        self.get_object().delete()
        return Response({'code': 100, 'msg': '删除成功'})

3.基于GenericAPIView与5个视图拓展类

(1)GenericAPIView的属性和方法

  • 属性

1)queryset:要序列化或者反序列化的表模型数据

2)serializer_class 使用的序列化类

3)lookup_field 查询单条的路由分组出来的字段名

4)filter_backends 过滤类的配置

5)pagination_class 分页器的配置

  • 方法

1)get_queryset 获取要序列化的对象

2)get_object 获取单个对象

3)get_serializer 获取序列化类,跟它差不多的get_serializer_class 一般重写

4)filter_queryset 过滤有关系

genericAPIView()

(2)5个视图拓展类

GenericAPIView封装了5个视图拓展类,分别对应5个接口

  • get请求 查询所有:ListModelMixin-->list方法
  • get请求 查询一个:RetrieveModelMixin-->Retrieve方法
  • post请求 新增一个:CreateModelMixin-->Create方法
  • put请求 修改一个:UpdateModelMixin-->Update方法
  • delete请求 删除一个:DestroyModelMixin-->Destroy方法

在5个视图类中,封装的不是get方法或者post方法,虽然名字不叫get方法或者post方法,但是和其内容一致

所以必须要配合 GenericAPIView 视图基类来使用,不然会报错

1.views.py中编写视图类

基于GenericAPIView封装的5个视图拓展类编写

from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    ListModelMixin


class BookView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = 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 = 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)

2.序列化类

class BookSerializer(serializers.ModelSerializer):
    # 跟表有关联
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'author_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }

3.路由

urlpatterns = [
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]

2、9个视图子类

9个视图子类,不需要额外继承GenericAPIView,只要继承9个中其中某个,就会有某个或某几个接口

1.9个视图子类对应的请求与功能

视图子类 请求 功能
CreateAPIView post 新增
ListAPIView get 查询所有
RetrieveAPIView get 查询一个
DestroyAPIView delete 删除
UpdateAPIView put、patch 修改
ListCreateAPIView get、post 查询所有、新增
RetrieveUpdateAPIView get、put、patch 查询一个、修改
RetrieveDestroyAPIView get、delete 查询一个、删除
RetrieveUpdateDestroyAPIView get、put、patch、delete 查询一个、修改、删除

2.基于9个视图子类编写接口

"第四层:基于9个视图子类编写接口"
from rest_framework.generics import ListAPIView, ListCreateAPIView, CreateAPIView, RetrieveAPIView, \
    RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView


# 查询所有 新增一个
class BookView(ListCreateAPIView):  # 查询所有新增一个
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # get 和 post通过继承已经写好了


# 查询一个,修改一个,删除一个
class BookDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # get put delete
  • ListCreateAPIView源码

image-20230206203059668

  • RetrieveUpdateDestroyAPIView源码

image-20230206203333916

3.多种混和编写接口

可以通过九个的组合,来实现多种功能的实现

(1)ListAPIView 查询所有, CreateAPIView 新增一个

(2)ListAPIView + CreateAPIView = ListCreateAPIView

(3)RetrieveAPIView 查询一个 , DestroyAPIView 删除 , UpdateAPIView 修改

(4)RetrieveDestroyAPIView 查找一个和删除 RetrieveUpdateAPIView查找一个和修改,但是不存在Destroy和Update的组合

(5)RetrieveUpdateDestroyAPIView 查询一个、修改、删除

3、视图集

第五层。五个接口还是需要写两个视图类,配置两条路由

  • 但是两个视图类写成一个,
    • 路由不同
    • 会有两个get方法
  • drf中的类 ModelViewSet 只要继承他,5个接口都有,但是路由写法变了

1.通过ModelViewSet类编写5个接口

路由的写法改变了,但是视图类只用写一个

  • 路由
# 路由
urlpatterns = [
    path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
    path('books/<int:pk>/', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]
  • 视图类
class BookView(ModelViewSet):  # 查询所有,新增一个
    queryset = Book.objects.all()
    serializer_class = BookSerializer

2.通过ReadOnlyModelViewSet编写只读接口

  • 路由
urlpatterns = [
    path('books/', views.BookView.as_view({'get': 'list'})),
    path('books/<int:pk>/', views.BookView.as_view({'get': 'retrieve'})),
]
  • 视图类
class BookView(ReadOnlyModelViewSet):  # 查询所有,新增一个
    queryset = Book.objects.all()
    serializer_class = BookSerializer

4.from rest_framework.viewsets包下的类

1.ModelViewSet - 路由写法变了,只需要写两行,5个接口都有

  • 5个视图扩展类
  • ViewSetMixin
  • GenericAPIView

2.ReadOnlyModelViewSet - 路由写法变了,只需要写两行,2个只读接口都有

  • 2个视图扩展类

  • ViewSetMixin

  • GenericAPIView

3.ViewSetMixin 魔法类

重写了as_view,所以只要继承ViewSetMixin后,路由的写法都需要变成映射方法

4.ViewSet - 想用APIView

  • ViewSetMixin + APIView

5.GenericViewSet - 想用GenericAPIView

  • ViewSetMixin + GenericAPIView
  • 想继承APIView,但是想改变路由写法并且视图类中方法名可以任意命名,需要继承ViewSet
  • 想继承GenericAPIView,但是想改变路由写法并且视图类中方法名可以任意命名,要继承GenericViewSet

5.路由写法改变的原因

(1)GenericViewSet

GenericViewSet =

导致路由配置改变了形式

view = MyViewSet.as_view({'get': 'list', 'post': 'create'})

(2)ViewSetMixin源码分析

-->属性的查找顺序从左往右,由于ViewSetMixin中有as_view方法,则先执行ViewSetMixin中的as_view方法

标签:ser,get,self,request,视图,组件,class,DRF
From: https://www.cnblogs.com/DuoDuosg/p/17096726.html

相关文章

  • drf 自动生成路由
    目录drf路由系统SimpleRouter与DefaultRouteraction装饰器扩展测试伪代码drf路由系统由于继承了ViewSetMinxin类路由的写法变了,有三种写法。需要学习一下原生写法pa......
  • def 认证组件
    目录drf认证组件登录接口viewsmodelsurlsdrf认证组件登录接口viewsfromrest_framework.viewsetsimportViewSetfromrest_framework.decoratorsimportactionfr......
  • 视图集/路由自动生成
    9个视图子类在此文件中fromrest_framework.generics有九个视图子类功能分别如下9个视图子类---视图类,不需要额外继承GenericAPIView,只需要继承9个中其中某个,就会有......
  • 视图层与路由系统
    视图层两个视图基类APIViewGenericAPIView5个视图扩展类fromrest_framework.mixinsimportCreateModelMinin,UpdateModelMixin,DestroyModelMixin,......
  • 视图组件与路由组件
    9个视图子类两个视图基类(是视图类):APIView,GenericAPIView五个视图扩展类(不是视图类,需要配合使用):CreateModelMixin,ListModelMixin,RetrieveModelMixin,UpdateMod......
  • 认证组件
    认证组件#访问某个接口:需要登录后才能访问#第一步:先写个登录功能,用户表 -User表-UserToken表:存储用户登录状态[这个表可以没有,如果没有,把字段直接写在User......
  • drf视图类 视图基类、视图扩展类、视图子类、视图集以及路由类
    drf视图类视图基类、视图扩展类、视图子类、视图集两个视图基类APIView这个视图类在前文已经介绍过了,web常见5个接口--APIView的最后有提到:APIView也是继承了django......
  • drf
    今日内容1.9个视图子类2.视图集3.路由系统4.认证组件1.9个视图子类两个视图基类5个视图扩展类9个视图子类----》视图类,不需要额外继承GenericAPIView,只需要继承9个......
  • Ant Design of Vue - 让 Message 组件支持手动点击关闭
    需求让antd的Message组件能够手动触发关闭Fromto思路查看antdv文档发现Message组件支持使用VNode作为显示内容,因此只需要使用Vue的createElement方......
  • Angular新建组件以及组件之间的调用
    场景Angular介绍、安装AngularCli、创建Angular项目入门教程在上面搭建好Angular项目。项目目录结构如下 注:关注公众号霸道的程序猿获取编程相关电子书、教程推送与免费......