13 视图组件

 

 

  

 

1 ,视图

两个视图基类

APIView
GenericAPIView

1.1 ,基于APIView写的5个接口

#### 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()),

1.2, 基于GenericAPIView写的5个接口

### views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Publish
from .seriazlizer import PublishSerializer

### 通过继承GenericAPIView写 5个接口

from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView  # 继承APIView,写了几个类属性

"""
# 类属性
queryset = None   # 所有数据
serializer_class = None  # 序列化的类
lookup_field = 'pk'  # 查询单条转换器的字段


# 三个方法
self.get_queryset()  # 获取所有的数据
self.get_serializer   # 获取序列化类
self.get_object()   # 获取单条数据
"""

class PublishView(GenericAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request):
        obj = self.get_queryset()
        ser = self.get_serializer(instance=obj, many=True)
        return Response(data=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)
        # ser.is_valid(raise_exception=True)


class PublishDetailView(GenericAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request, pk):
        obj = self.get_object()  # 获取单条 ,根据pk
        ser = PublishSerializer(instance=obj)
        return Response(data=ser.data)

    def put(self, request, pk):
        obj = self.get_object()  # 数据不存在 ,None,如果instance是None,ser.save -->是新增
        ser = self.get_serializer(data=request.data, instance=obj)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        else:
            return Response(ser.errors)
        # ser.is_valid(raise_exception=True)

    def delete(self, request, pk):
        res = self.get_object().delete()  # 返回影响的行数
        if res >= 1:
            return Response()
        else:
            return Response('要删除的数据不存在')

###urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('publish/',views.PublishView.as_view()),
    path('publish/<int:pk>',views.PublishDetailView.as_view()),

###models.py
class Publish(models.Model):
    name = models.CharField(max_length=16)
    address = models.CharField(max_length=64)

####serializer.py
class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model = Publish
        fields = "__all__"

 

1.3 基于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()),

9个视图子类

class ListAPIView(GenericAPIView,ListModelMixin):
    def get(self,request):
        return self.list(request)

class CreateAPIView(GenericAPIView,CreateModelMixin):
    def post(self,request):
        return self.create(request)

class ListCreateAPIView(GenericAPIView,ListModelMixin,CreateModelMixin):
    def get(self, request):
        return self.list(request)

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

class DestroyAPIView(GenericAPIView,DestroyModelMixin):
    def delete(self, request, pk):
        return self.destroy(request, pk)

class UpdateAPIView(GenericAPIView,UpdateModelMixin):
    def put(self, request, pk):
        return self.update(request, pk)

class RetrieveAPIView(GenericAPIView,RetrieveModelMixin):
    def get(self, request, pk):
        return self.retrieve(request, pk)

class RetrieveDestroyAPIView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin):
def get(self, request, pk):
return self.retrieve(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)


class RetrieveUpdateAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin):
def get(self, request, pk):
return self.retrieve(request, pk)
def put(self, request, pk):
return self.update(request, pk)

class RetrieveUpdateDestroyAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
def get(self, request, pk):
return self.retrieve(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
def put(self, request, pk):
return self.update(request, pk)

1.4 使用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'})),

1.5 源码分析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

1.6 继承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'})),

1.1视图继承关系

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

总结:

#两个基类
APIView
GenericAPIView:有关数据库操作,queryset 和serializer_class


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

#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删除

#视图集
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

补充

1 在pycharm中查看类的继承关系

 

 

 

 

 

 

 

posted @ 2021-12-22 22:06  甜甜de微笑  阅读(45)  评论(0编辑  收藏  举报