## 1.一级视图:    APIView

​    封装了request和response


```python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status    # 封装状态码

class UserAPIView(APIView):
    def get(self, request):
        """
            get请求: request.query_params.get(**)
            post/file/*: request.data.get(**)
        """
        return Response([{'id': 1, 'name': 'xslee'}], status=status.HTTP_201_CREATED)
```


## 2.二级视图:    GenericAPIView

​    继承自APIView,     一般与Mixin类组合使用
​    

```python
from rest_framework.generics import GenericAPIView
class MView(GenericAPIView):
    queryset = Blog.objects.all()    
    serializer_class = UserSerializer
    lookup_field = 'pk'
    
    def get(self, request, user_id):
        self.get_queryset()
        self.get_serializer()
        self.get_object()
```

```python
三属性&&三方法:
1. queryset                    # 指定查询集
2. serializer_class            # 指定序列化器
3. lookup_field                # 模型字段名(pk/id), 源码中为pk

1. self.get_queryset()        # 获取查询集
2. self.get_serializer(queryset, many=True)    # 获取序列化器
3. self.get_object()        # 只用在详情试图下获取当前user_id实例化对象, 由系统根据pk/id自动查找

"""
lookup_field&&lookup_url_kwargs
lookup_field        对应的指定的是模型类中用来查询的字段一般是pk/id
lookup_field='pk/id'    指定根据User模型类的id查找

lookup_url_kwargs    对应的是url中的命名参数(方法参数)
lookup_url_kwargs=user_id
.../users/(?P<user_id>\d+)/$    
def get(self, request, user_id)
方法参数user_id要与命名参数user_id保持一致, 由lookup_url_kwargs指定
"""
class BlogsView(GenericAPIView):
    queryset = Blog.objects.all()
    serializer_class = BlogSerializer

    def get(self, request):
        blogs = self.get_queryset()
        serializer = self.get_serializer(blogs, many=True)
        serializer.data        # 序列化后的数据
        return Response({'status': status.HTTP_200_OK, 'blogs': serializer.data})
```


​                



## 3.Mixin混合类:

​    配合GenericAPIView, 提供模型的LCURD通用功能

```python
from rest_framework.mixins import ListModelMixin        
from rest_framework.mixins import CreateModelMixin        # 自定义保持规则, 重写perform_create(self, serializer)方法
from rest_framework.mixins import UpdateModelMixin        # 自定义更新, 重写perform_update(self, serializer)方法
from rest_framework.mixins import RetrieveModelMixin        # put->retrieve 获取单条数据
from rest_framework.mixins import DestroyModelMixin
```



## 4.三级通用视图: 

​    继承自GenericAPIView:
​        LCURD+GenericAPIView        # 不使用大量的自定义行为

```python
from rest_framework.generics import ListAPIView        
from rest_framework.generics import CreateAPIView
from rest_framework.generics import UpdateAPIView
from rest_framework.generics import RetrieveAPIView
from rest_framework.generics import DestroyAPIView
# LC+URD

class GoodsSpuLCAPIView(ListCreateAPIView):
    authentication_classes = [LoginAuthentication, ]
    queryset = GoodsSpu.objects.order_by().all()
    serializer_class = GoodsSkuSerializer4Params
    pagination_class = ListPagination

    def get_queryset(self):
        query = self.request.query_params.get('query', '')
        if query:
            return self.queryset.filter(name__contains=query)
        return self.queryset
    
    
 class GoodsSpuRUDAPIView(RetrieveUpdateDestroyAPIView):
    authentication_classes = [LoginAuthentication, ]
    queryset = GoodsSpu.objects.all()
    serializer_class = GoodsSkuSerializer4Params
    lookup_field = 'pk'
    lookup_url_kwarg = 'goodsSpu_id'
```



## 4.视图集:

```python
from rest_framework.viewsets import ViewSet
from rest_framework.viewsets import GenericViewSet
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.viewsets import ModelViewSet
# 在as_view()中, 指定方法与标准请求方式的映射  as_view({'get': 'list', 'post': 'create'.....})     一般配合路由使用
```

```python
1. ViewSet
    继承自APIView
```

    2. GenericViewSet
        继承自GenericAPIView, 拥有三属性三方法, 自定义方法时, 在as_view中映射
    
    3. ReadOnlyModelViewSet
        继承自GenericViewSet + LRMixin    拥有三属性三方法, 不修改数据, 只用来获取数据
    
    4. ModelViewSet
        继承自GenericViewSet + LCURDMixin    


    5. 视图集的额外动作:    partial    # 允许前端传递模型部分字段数据用来更新
    
        ser = self.get_serializer(..., partial=True)        
        前端可以只传递模型部分字段{'name': 'xs'}









```python
# # authentications.py
class LoginAuthentication(BaseAuthentication):
    """
        继承BaseAuthentication类,重写authenticate方法。
    """
    def authenticate(self, request):
        token = request.META.get('HTTP_AUTHORIZATION')
        try:
            user_token = UserToken.objects.get(token=token)
        except UserToken.DoesNotExist as e:
            raise exceptions.AuthenticationFailed("验证失败")
        return user_token.user, user_token
        # views中 request.user, request.auth =  user_token.user, user_token

    def authenticate_header(self, request):
        pass

    

# # pagination.py
class UserListPagination(PageNumberPagination):
    page_query_param = 'pagenum'
    page_size_query_param = 'pagesize'
    max_page_size = 10

    def get_paginated_response(self, data):
        return Response({
            'data': {
                'count': self.page.paginator.count,     # 数据总数
                'users': data,  # 当前页集
                'page': self.page.number,   # 第*页
                'pages': self.page.paginator.num_pages,  # 总页数
                'pagesize': self.request.query_params.get('pagesize') or self.max_page_size,    # 当前页数据量
                # ('next', self.get_next_link()),
                # ('previous', self.get_previous_link()),
            },
            'meta': {
                'status': status.HTTP_200_OK,
                'msg': '获取用户成功'
            }

        })

    
    

# # serializers.py
class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(max_length=15, min_length=6, write_only=True)

    class Meta:
        model = Users
        fields = ('id', 'username', 'email', 'is_active', 'password')
        extra_kwargs = {
            """'username': {
                'read_only': True,
            }"""
        }

    def validated_password(self, value):
        if 6 <= len(value) <= 15:
            return value
        raise serializers.ValidationError(u"密码长度不合法, 密码6-15位")
       
    def create(self, validated_data):
        user = Users.objects.create(
            username=validated_data.get('username'),
            email=validated_data.get('email'),
        )
        user.set_password(validated_data.get('password'))
        user.save()
        return user
    
    def update(self, instance, validated_data):
        instance.is_active = validated_data.get('is_active')
        instance.email = validated_data.get('email')
        instance.set_password(validated_data.get('password'))
        instance.save()
        return instance
        
    
# # views.py
class UserListAPIView(ListAPIView):
    authentication_classes = [LoginAuthentication]
    pagination_class = UserListPagination
    serializer_class = UserSerializer
    queryset = Users.objects.filter(is_superuser=0).order_by('id').all()

    def get_queryset(self):
        query = self.request.query_params.get('query')
        if not query:
            return self.queryset
        return Users.objects.filter(username__contains=query).order_by('id').all()

# # urls.py
url(r'^users/', views.UserListAPIView.as_view(), name='users')

/bk/users/?query=xs&pagenum=1&pagesize=2
/bk/users/?query=&pagenum=1&pagesize=2
```