rest-framework框架——视图和认证组件

一、mixins类编写视图

1、配置url

urlpatterns = [
    ...
    re_path(r'^authors/$', views.AuthorView.as_view(), name="author"),
    re_path(r'^authors/(?P<pk>\d+)/$', views.AuthorDetailView.as_view(), name="detail_author")
]

2、编写Author的序列化类

/app01/serializer.py:

class AuthorModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = "__all__"

3、编写Author的视图

# Author
from rest_framework import mixins, generics


class AuthorView(mixins.ListModelMixin,        # 扩展了列出查询集功能
                 mixins.CreateModelMixin,      # 扩展了创建和保存新模型实例功能
                 generics.GenericAPIView):     # 继承扩展了REST框架的APIView类,为标准列表和详细视图添加了常见的行为
    queryset = Author.objects.all()     # 配置queryset:告知这个类这次处理的数据
    serializer_class = AuthorModelSerializers     # 告知处理用到的序列化组件

    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 AuthorDetailView(mixins.RetrieveModelMixin,   # 扩展在响应中实现返回现有模型实例功能(获取单条数据)
                       mixins.DestroyModelMixin,    # 扩展现有模型实例的删除功能
                       mixins.UpdateModelMixin,     # 扩展更新和保存现有模型实例功能
                       generics.GenericAPIView):
    queryset = Author.objects.all()     # 配置queryset:告知这个类这次处理的数据
    serializer_class = AuthorModelSerializers     # 告知处理用到的序列化组件

    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)

  注意:

(1)queryset和serializer_class变量

  这两个变量是必须的。queryset告知这个类这次处理的数据。serializer_class告知这个类数据处理用到的序列化组件。

(2)五类mixins作用和对应的http方法

  

(3)GenericAPIView

  这个类扩展了REST框架的APIView类,为标准列表和详细视图添加了常见的行为。

  提供的每个具体的通用视图都是通过把GenericAPIView与一个或多个mixin类进行组合来构建的。

(4)测试验证

   

二、Mixins源码分析

1、CreateModelMixin

class CreateModelMixin(object):
    """Create a model instance ==>创建一个实例"""
    def create(self, request, *args, **kwargs):
        # 获取相关serializer
        serializer = self.get_serializer(data=request.data)
        
        # 进行serializer的验证;raise_exception=True,一旦验证不通过,不再往下执行,直接引发异常
        serializer.is_valid(raise_exception=True)
        
        # 调用perform_create()方法,保存实例
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
    # 保存实例
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}

  注意:

(1)perform_create( )对serializer直接进行save保存,当在一些情境下,需要对perform_create( )进行重写。

(2)这个类的运行流程如下所示:

  

扫描二维码关注公众号,回复: 3026356 查看本文章

2、ListModelMixin

class ListModelMixin(object):
    """List a queryset.==> 列表页获取"""
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        
        # 这是一个分页功能,如果在viewset中设置了pagination_class,那么这里就会起作用
        # 获取当前页的queryset,如果不存在分页,返回None
        page = self.paginate_queryset(queryset)
        
        if page is not None:
        # 分页不为空,那么不能简单的执行Response(serializer.data)
        # 还需要将相关的page信息序列化在进行响应
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

  ListModelMixin一般用来获取列表页,不需要重写方法。

3、RetriveModelMixin

class RetrieveModelMixin(object):
    """
    Retrieve a model instance.==> 获取某一个对象的具体信息
    """
    def retrieve(self, request, *args, **kwargs):
        # 一般访问的url都为/obj/id/这种新式
        # get_object()可以获取到这个id的对象
        # 注意在viewset中设置lookup_field获取重写get_object()方法可以指定id具体对象是什么~!
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

4、DestoryModelMixin

class DestroyModelMixin(object):
    """
    Destroy a model instance.
    """
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)

    def perform_destroy(self, instance):
        instance.delete()

5、总结

  这一章简要分析了源码的内容以及各个mixins的逻辑,最重要的还是学会重写它们相关的方法。一般情况下,当我们在操作某一个model的时候,涉及到另外一个model中数据的修改,那么就需要对这个mixins下执行save的逻辑的方法进行重写。

猜你喜欢

转载自www.cnblogs.com/xiugeng/p/9576582.html