您的位置:首页 > 聚焦 > 正文
drf——5个视图扩展类、9个视图子类、视图集、drf之路由|全球快资讯
来源:博客园 发布时间2023-05-24 00:55:51    


(资料图)

5个视图扩展类
# 写5个类(不叫视图类 视图拓展类 需要配合GenericAPIView一起用) 每个类有一个方法 以后想写哪个接口 就继承哪个类即可from rest_framework.response import Response####自己封装的5个视图拓展类class ListModelMixin:    def list(self,request):        qs = self.get_queryset()        ser = self.get_serializer(qs,many=True)        return Response({"code":100,"msg":"成功","result":ser.data})class CreateModelMinxin:    def create(self,request):        ser = self.get_serializer(data=request.data)        if ser.is_valid():            ser.save()            return Response({"code":100,"msg":"成功"})        else:            return Response({"code":100,"msg":"失败"})class RetrieveModelMixin:    def retrieve(self,request,*args,**kwargs):        qs = self.get_object()        ser = self.get_serializer(qs)        return Response({"code":100,"msg":"成功","result":ser.data})class UpdateModelMixin:    def update(self,request,*args,**kwargs):        qs = self.get_object()        ser = self.get_serializer(qs,data=request.data)        if ser.is_valid():            ser.save()            return Response({"code":100,"msg":"成功"})        else:            return Response({"code": 100, "msg": "失败"})class DestroyModelMixin:    def destroy(self,request,*args,**kwargs):        qs = self.get_object()        qs.delete()        return Response({"code":100,"msg":"成功"})    #### drf封装好的from .models import Bookfrom .serializer import BookSerializerfrom rest_framework.response import Responsefrom rest_framework.generics import GenericAPIViewfrom rest_framework.mixins import ListModelMixin,CreateModelMinxin,UpdateModelMinxin,DestroyModelMixin,RetrieveModelMixinclass 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.object.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)
# 5个视图扩展类(不是视图类)---》必须配合GenericAPIView及其子类使用---》不能配合APIView使用# 5个视图扩展类 每一个类中只有一个方法 完成5个接口中的其中一个 想写多个接口 就要继承多个
9个视图子类
"""基于视图子类写接口 9个视图子类--->视图类"""from rest_framework.generics import ListAPIView,CreateAPIView,RetrieveAPIView,UpdateAPIView,DestroyAPIViewfrom rest_framework.generics import ListCreateAPIViewfrom rest_framework.generics import RetrieveUpdateDestroyAPIViewfrom rest_framework.generics import RetrieveUpdateAPIViewfrom rest_framework.generics import RetrieveDestroyAPIView# from rest_framework.generics import UpdateDestroyAPIView  # 这个没有# ModelViewSet:继承它后 只需要在视图类中写两行    queryset = Book.objects.all()        serializer_class = BookSerializer    配置路由,5个接口都有了    path("books/", BookView.as_view({"get": "list", "post": "create"})),    path("books//", BookView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),   ######def list(self, request, *args, **kwargs):        res = super().list(request,*args,**kwargs)        return Response({"code": 100, "msg": "成功", "data": res.data})可以重写父类中的方法 但是一定不能用self. 必须使用super() 否则会递归        # ModelViewSet 源码分析继承了:    mixins.CreateModelMixin,                  mixins.RetrieveModelMixin,                  mixins.UpdateModelMixin,                  mixins.DestroyModelMixin,                  mixins.ListModelMixin,                  GenericViewSet                    ViewSetMixin : 重写看as_view方法                        GenericAPIView           只要继承了ModelViewSet,路由写法变了,谁控制它变的:ViewSetMixin        # ViewSetMixin 如何控制路由写法变了?(源码如下)BookView.as_view 是在执行ViewSetMixin的as_view    @classonlymethod        def as_view(cls,actions=None,**initkwargs):            # 我们传入的 actions={"get":"list","post":"create"}            def view(request,*args,**kwargs):                self = cls(**initkwargs)                for method,action in actions.items():                    # method:get                    # action:list                    # 通过反射 self是BookView的对象 去BookView对象中反射list                    hander = getattr(self,action)                    # 通过反射:setattr(BookView的对象,"get",list方法)                    setattr(self,method,handler)                # APIView的dispatch                return self.dispatch(request,*args,**kwargs)            return csrf_exempt(view)        # 总结:"""1.只要继承了ViewSetMixin及其子类,路由写法就变了,必须传actions参数2.变成映射关系了:path("books/", BookView.as_view({"get": "list", "post": "create"})),3.以后 只要是books路由匹配成功的get请求 就会执行视图类BookView的list方法4.用户视图类中的方法名 可以随意命名5.这个类 必须配合视图类使用(APIView,GenericAPIView,9个视图子类),必须放在视图类之前"""
视图集
# 两个视图基类APIView    GenericAPIView# 5个视图扩展类(不是视图类 需要配合GenericAPIView及其子类使用)# 9个视图子类# 视图集:ModelViewSet:5个接口的    ReadOnlyModelViewSet:两个接口 list和retrieve    ViewSetMixin:魔法 不能单独使用,必须配合视图类用 路由写法变了    ViewSet:ViewSetMixin + APIView 以后想继承APIView 但是想路由写法变化 视图类中方法可以任意命名    GenericViewSet:ViewSetMixin + GenericAPIView 以后想继承GenericAPIView 但是想路由写法变化 视图类中方法可以任意命名
drf之路由
# 路由的写法有多种原始写法    映射的写法:path("books/",BookView.as_view({"get":"list","post":"create"}))    自动生成路由    # 自动生成路由必须要继承ViewSetMixin及其子类的视图类,才能用    继承了 5个视图扩展类+ViewSetMixin的视图类,能自动生成路由(ModelViewSet)跟咱们写的这个是一样的        path("books/", BookView.as_view({"get": "list", "post": "create"})),        path("books//", BookView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"}))   """第一步 导入一个路由类"""from rest_framework.routers import SimpleRouter"""第二步 实例化得到对象"""router = SimpleRouter()"""第三步 注册路由(视图类) 第一个参数是前缀 第二个参数是视图类 第三个参数是别名"""router.register("books",BookView,"books")# http://127.0.0.1:8000/api/v1/books/books/# 第一个books是注册路由时的前缀 第二个books是action装饰器的url_path参数"""第四部 加入到路由中"""# 4.1 方式一# urlpatterns += router.urls# 4.2 方式二# 使用include  path("api/v1/", include(router.urls)),          # 自动生成路由1.继承了 5个视图扩展类 + ViewSetMixin的视图类 能自动生成路由    (get:list,get:retrieve..)    2. 我们自己命名的: 方法名:login  send_sms,需要使用装饰器来做    # 视图类        class SMSView(ViewSet):            @action(methods=["GET"], detail=False, url_path="lqz", url_name="lqz")            def lqz(self, request):                return Response("你好")        # 路由        router.register("lqz",SMSView,"lqz")        # 路径是:http://127.0.0.1:8000/api/v1/lqz/lqz/  第一个是前缀第二个是url_path的参数 如果没有就是函数名    3.action装饰器的参数    methods:请求方式 是以列表的形式        detail:一个True,一个False,用True,表示生成详情的路径             # True books/1/方法名/            # False,books/方法名/        url_path:路径名字 需要加上前面的路径一起 如果不给这个参数 则默认以函数名作为路径名        url_name:反向解析使用的名字(用的不多)                # 路由类,有两个,用法完全一致,区别是DefaultRouter生成的路径多    SimpleRouter :用的最多    DefaultRouter    # DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据(提示你可以访问哪些路径)。

关键词:

推荐内容