day85

1 2个视图基类 2 5个视图扩展类 3 9个子类视图 4 视图集 5 action的使用 6 路由的使用

## 1 2个视图基类

```python
# 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 5个视图扩展类

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



## 3 9个子类视图

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



## 4 视图集

```python
#视图集

# 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
```



## 5 action的使用

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





## 6 路由的使用

```python
# 自动生成路由
# SimpleRouter
# DefaultRouter

# (前提)继承了ViewSetMixin的视图类,以后写路由,可以自动生成
# 在urls.py中:
from rest_framework import routers
# 实例化得到一个对象
router = routers.SimpleRouter()
# 注册进路由(  router.register(路由关系, 视图类)     )
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是基于带pk的路由生成的,如果是False,是基于不带pk的路由生成的
        -@action(methods=['get'], detail=True)

```

 

urls.py

from django.contrib import admin
from django.urls import path, re_path
from app01 import views
from rest_framework import routers

router = routers.SimpleRouter()     # 实例化得到对象
# router = routers.DefaultRouter()
router.register('books', views.BookSetView, basename='book')     # 注册
print(router.urls)
urlpatterns = [
    path('admin/', admin.site.urls),
    # path('books/', views.BookAPIView.as_view()),
    # path('books/', views.BookGenericView.as_view()),
    # re_path('^books/(?P<pk>\d+)', views.BookDetailGenericAPIView.as_view()),
]
urlpatterns += router.urls

views.py

from django.shortcuts import render

# Create your views here.
from app01 import serializer
from app01 import models
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView

# 两个视图基类(APIView、GenericAPIView)
# ①APIView
'''
class BookAPIView(APIView):
    def get(self, request):
        book_list = models.Book.objects.all()
        ser = serializer.BookModelSerializer(instance=book_list, many=True)
        return Response(ser.data)

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

# ②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(instance=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('success')


class BookDetailGenericView(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('update_success')

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

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


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)
'''

# 九个视图子类(九种组合)
'''
# 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删除

from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    UpdateModelMixin
from rest_framework.generics import CreateAPIView, ListAPIView, ListCreateAPIView
from rest_framework.generics import UpdateAPIView, RetrieveAPIView, DestroyAPIView, RetrieveUpdateAPIView, \
    RetrieveDestroyAPIView, RetrieveUpdateDestroyAPIView


# 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)
# class BookGenericView(CreateListGenericAPIView):
#     queryset = models.Book.objects.all()
#     serializer_class = serializer.BookModelSerializer


# class BookGenericView(ListAPIView):     # 仅新增
# class BookGenericView(ListCreateAPIView):     # 新增和查询多条
# class BookDetailGenericAPIView(RetrieveAPIView):      # 查询一条
# class BookDetailGenericAPIView(RetrieveAPIView,UpdateAPIView):        # 查询一条和修改
class BookDetailGenericAPIView(RetrieveUpdateDestroyAPIView):         # 查询一条,修改,删除
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer
'''

# 视图集
'''
# 继承ModelViewSet,有5个接口
from rest_framework.viewsets import ModelViewSet
from rest_framework.viewsets import ReadOnlyModelViewSet    # 只有查询(只读)
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):    # ViewSet继承了ViewSetMixin,ViewSetMixin中重写了as_view()方法
    def lqz(self, request, *args, **kwargs):
        print(self.action)      # 继承ViewSet后才有self.action属性
        return Response('lqz')

    def egon(self, request, *args, **kwargs):
        return Response('egon')
    # 在urls.py中:
    # path('books_mix/', views.BookView.as_view({'get':'lqz'})),
    # path('books_mix2/', views.BookView.as_view({'get':'egon'})),
'''

# 自动生成路由
'''
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
class BookSetView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer

    @action(methods=['get'], detail=True)       # detail=True时自动生成的路由:^books/(?P<pk>[^/.]+)/login/$ [name='book-login']
    def login(self, request, *args, **kwargs):
        print(args)
        print(kwargs)
        return Response('login successfully')

    @action(methods=['post'], detail=False)     # detail=False时自动生成的路由:^books/register/$ [name='book-register']
    def register(self, request, *args, **kwargs):
        print(args)
        print(kwargs)
        return Response('register successfully')
'''

 

上一篇:20201112-1 函数式编程之参数详解2


下一篇:Django Rest Framework 源码相关