drf—— 视图组件

一、2个视图基类

1.储备知识

# Django REST framwork 提供的视图的主要作用:
    控制序列化器的执行(检验、保存、转换数据)
    控制数据库查询的执行
# APIView:继承了原生Django的View
# GenericAPIView:继承了APIView
    -queryset = models.Book.objects.all()
    -serializer_class = serializer.BookModelSerializer
    -get_queryset:获取配置的queryset
    -get_object:路由中的分组字段必须是pk
    -get_serializer:获取配置的序列化类
       
    
# 最终总结
#两个基类
APIView:如果跟models没有关系(没有数据库相关操作),就继承它
GenericAPIView:有关数据库操作,queryset 和serializer_class

2.代码

models.py

from django.db import models

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32,null=True)
    price = models.DecimalField(max_digits=5, decimal_places=2,null=True)
    publish = models.CharField(max_length=32,null=True)
serializer.py
from app01 import models
from rest_framework import serializers

class BookModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Book
        fields = '__all__'

urls.py

from django.urls import path,re_path
from app01 import views

urlpatterns = [
    #继承APIView
    # path('books/',views.BookAPIView.as_view()),
    # re_path('^books/(?P<pk>\d+)', views.BookDetailAPIView.as_view()),
    #继承GenericAPIView
    path('books/',views.BookGenericView.as_view()),
    re_path('^books/(?P<pk>\d+)', views.BookDetailGenericAPIView.as_view()),

]

views.py----->继承了APIView

# 继承了APIView
class BookAPIView(APIView):
    def get(self, request):
        book_list = models.Book.objects.all()
        ser = serializer.BookModelSerializer(book_list, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = serializer.BookModelSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
        return Response('成功')


class BookDetailAPIView(APIView):
    def get(self, request, pk):
        book = models.Book.objects.get(id=pk)
        ser = serializer.BookModelSerializer(book)
        return Response(ser.data)

    def put(self, request, pk):
        book = models.Book.objects.get(id=pk)
        ser = serializer.BookModelSerializer(book, data=request.data)
        if ser.is_valid():
            ser.save()
        return Response('修改成功')

    def delete(self, request, pk):
        models.Book.objects.filter(id=pk).delete()
        return Response('删除成功')

views.py----->继承了GenericAPIView

#继承了GenericAPIView
class BookGenericView(GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

    def get(self, request, *args, **kwargs):
        obj = self.get_queryset()
        ser = self.get_serializer(obj, many=True)
        return Response(ser.data)
    def post(self, request, *args, **kwargs):
        ser=self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
        return Response('成功')

class BookDetailGenericAPIView(GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

    def get(self, request, *args, **kwargs):
        obj = self.get_object()
        ser = self.get_serializer(obj)
        return Response(ser.data)

    def put(self, request, *args, **kwargs):
        obj = self.get_object()
        ser = self.get_serializer(obj, data=request.data)
        if ser.is_valid():
            ser.save()
        return Response('修改成功')

    def delete(self, request, *args, **kwargs):
        self.queryset.filter(id=kwargs.get('pk')).delete()
        return Response('删除成功')

二、自定义两个扩展类

需要修改views.py  ------演变过程

#自定义了两个扩展类
class ListView():
    def list(self,request, *args, **kwargs):
        obj = self.get_queryset()
        ser = self.get_serializer(obj, many=True)
        return Response(ser.data)

class CreateView():
    def create(self,request, *args, **kwargs):
        ser=self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
        return Response('成功')
class BookGenericView(GenericAPIView,CreateView,ListView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)



class BookDetailGenericAPIView(GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

    def get(self, request, *args, **kwargs):
        obj = self.get_object()
        ser = self.get_serializer(obj)
        return Response(ser.data)

    def put(self, request, *args, **kwargs):
        obj = self.get_object()
        ser = self.get_serializer(obj, data=request.data)
        if ser.is_valid():
            ser.save()
        return Response('修改成功')

    def delete(self, request, *args, **kwargs):
        self.queryset.filter(id=kwargs.get('pk')).delete()
        return Response('删除成功')
#自定义了两个扩展类

三、5个视图扩展类

1.知识储备

#5个视图扩展类(rest_framework.mixins)
CreateModelMixin:create方法创建一条
DestroyModelMixin:destory方法删除一条
ListModelMixin:list方法获取所有
RetrieveModelMixin:retrieve获取一条
UpdateModelMixin:update修改一条

2.代码

需要修改views.py  ------演变过程

### 使用drf提供的视图扩展类
##5个视图扩展类
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin
    
class BookGenericView(GenericAPIView,ListModelMixin,CreateModelMixin):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class BookDetailGenericAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

    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)

四、9个子类视图

1.知识储备

#9个子类视图(rest_framework.generics)
CreateAPIView:继承CreateModelMixin,GenericAPIView,有post方法,新增数据
DestroyAPIView:继承DestroyModelMixin,GenericAPIView,有delete方法,删除数据
ListAPIView:继承ListModelMixin,GenericAPIView,有get方法获取所有
UpdateAPIView:继承UpdateModelMixin,GenericAPIView,有put和patch方法,修改数据
RetrieveAPIView:继承RetrieveModelMixin,GenericAPIView,有get方法,获取一条


ListCreateAPIView:继承ListModelMixin,CreateModelMixin,GenericAPIView,有get获取所有,post方法新增
RetrieveDestroyAPIView:继承RetrieveModelMixin,DestroyModelMixin,GenericAPIView,有get方法获取一条,delete方法删除
RetrieveUpdateAPIView:继承RetrieveModelMixin,UpdateModelMixin,GenericAPIView,有get获取一条,put,patch修改
RetrieveUpdateDestroyAPIView:继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView,有get获取一条,put,patch修改,delete删除

2.代码

from rest_framework.mixins import ListModelMixin, CreateModelMixin
#### 9个视图子类
class CreateListGenericAPIView(GenericAPIView,CreateModelMixin,ListModelMixin):
    def get(self,request,*args,**kwargs):
        return self.list(request,*args,**kwargs)
    def post(self,request,*args,**kwargs):
        return  self.create(request,*args,**kwargs)
from rest_framework.generics import CreateAPIView,ListAPIView,ListCreateAPIView from rest_framework.generics import UpdateAPIView,RetrieveAPIView,DestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView,\
RetrieveUpdateDestroyAPIView
# class BookGenericView(CreateAPIView): # class BookGenericView(ListAPIView): class BookGenericView(ListCreateAPIView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer # class BookDetailGenericAPIView(RetrieveAPIView): # class BookDetailGenericAPIView(RetrieveAPIView,UpdateAPIView): class BookDetailGenericAPIView(RetrieveUpdateDestroyAPIView): queryset = models.Book.objects.all() serializer_class = serializer.BookModelSerializer

五、视图集

1.储备知识

#视图集

# ViewSetMixin:重写了as_view 

# ViewSet:     继承ViewSetMixin和APIView
# GenericViewSet:继承ViewSetMixin, generics.GenericAPIView

# ModelViewSet:继承mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,\
mixins.ListModelMixin,GenericViewSet
# ReadOnlyModelViewSet:继承mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet

2.代码

urls.py

urlpatterns = [
    # ## 使用视图集
    # path('books_set/', views.BookSetView.as_view({'get':'list','post':'create'})),
    # # path('books_set/', views.BookSetView.as_view()), # 直接报错
    # re_path('^books_set/(?P<pk>\d+)', views.BookSetView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
    #
    path('books_mix/', views.BookView.as_view({'get':'lili'})),
    path('books_mix2/', views.BookView.as_view({'get':'xxx'})),

]

views.py

# 视图集
# 继承一个东西,有5个接口
from rest_framework.viewsets import ModelViewSet
from rest_framework.viewsets import ReadOnlyModelViewSet # 只有查询
from rest_framework.views import APIView
class BookSetView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

# ViewSetMixin:视图类中的方法名,可以随便写,只需要映射对就可以
from rest_framework.viewsets import ViewSetMixin,ViewSet

# class BookView(ViewSetMixin,APIView):
class BookView(ViewSet):
    def lili(self,request,*args,**kwargs):
        print(self.action)
        return Response('lili')

    def xxx(self,request,*args,**kwargs):
        return Response('xxxx')

六、action的使用

# 只要继承了ViewSetMixin类
# 路由配置:path('books_mix/', views.BookView.as_view({'get':'lili'}))
# 视图类的方法中就会有个action
class BookView(ViewSet):
    def lili(self,request,*args,**kwargs):
        print(self.action)
        return Response('lili')
    
    
# ViewSetMixin以后只要继承它,路由的配置就发生变化了,只需要写映射即可

七、路由的使用

# 自动生成路由
# SimpleRouter
# DefaultRouter

# 继承了ViewSetMixin的视图类,以后写路由,可以自动生成
from rest_framework import routers
# 实例化得到一个对象
router = routers.SimpleRouter()
# 注册进路由
router.register('books', views.BookSetView)
# 把自动生成的路由配置到urlpatterns中
    -urlpatterns += router.urls
    -re_path(r'v1/', include(router.urls))    
    
    
# 配置路由的方式
    -最原始的
        -path('books/', views.BookAPIView.as_view()),
    -ViewSetMixin的视图类
        -path('books_set/', views.BookSetView.as_view({'get':'list','post':'create'}))
    -ViewSetMixin的视图类
        -自动生成,上面讲的              
        
        
 # action
    -当自动生成路由的时候,由于视图类中还有其它方法,是无法自动生成路由的
    -加action装饰器:
        -methods:什么请求方式会触发被装饰函数的执行
        -detail:是True是基于带id的路由生成的,如果是False,是基于不带id的路由生成的
        -@action(methods=['get'], detail=True)

 

posted @ 2020-11-05 15:12  1024bits  阅读(63)  评论(0编辑  收藏  举报