您的位置:首页 > 编程语言 > Go语言

DRF(Django rest_framework)中主要的类视图

2018-07-19 10:21 756 查看

DRF类视图简介

一、DRF类视图的两个基类

1.1 APIView

# rest_framework.views.APIView
# 源码
def as_view(cls, **initkwargs):
pass
def get_authenticators(self):
pass
def get_throttles(self):
pass
...
[/code]

主要实现
APIException异常捕获
authentication_classes(,)/[ ] 用于身份认证
permission_classes(,)/[ ] 权限检查
throttle_classes(,)/[ ] 流量控制
没有实现
get()/post()/delete()/update()的封装
数据库的查询集/序列化器的指定
Request
Response 需要导入rest_framework.response

class UserNameCheckView(APIView):
"""用户名是否已经存在"""
# GET usernames/(?P<username>\w{5,20})/count/
def get(self, request, username):
# 查询数据库,判断username是否存在
count = User.objects.filter(username=username).count()
# JSON username, count
data = {
'username': username,
'count': count
}
return Response(data)
[/code]

1.2 GenericAPIView

# rest_framework.generic.GenericAPIView
# 源码
# 指定查询集
queryset = None
# 指定序列化器
serializer_class = None
# 获得查询集
def get_queryset(self):
pass
# 获得查询对象
def get_object(self):
pass
# 获得序列化器
def get_serializer(self, *args, **kwargs):
pass
def get_serializer_class(self):
pass
def get_serializer_context(self):
pass
....
[/code]

主要实现查询集和序列化器指定
serializer_class 指明视图使用的序列化器(只能指明一个)
get_serializer_class(self) 通过函数的形式根据条件,返回指定的序列化器(有选择的返回)
get_serializer(self, *args, **kwargs) 返回序列化对象 注意
queryset 指定使用的查询集
get_queryset(self) 返回指定的查询集
get_object(self) 返回模型类对象,如果不存在响应404
pagination_class 指明分页控制类
filter_backends 过滤控制后端
没有实现
get()/post()/delete()/update()的封装

# 通常搭配Mixin使用列子在扩展类中一起列举

二、五个扩展类

这五个扩展类本质是Mixin类,封装筛选、序列化过程(get()/post()/delete()/update()…的封装),封装并返回响应等,需要搭配GenericAPIView使用,继承查询集和序列化指定,封装响应

# 2.1 ListModelMixin 列表视图扩展类 -- list
# 源码
class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

page = self.paginate_queryset(queryset)
if page is not None:
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)
# 2.2	RetrieveModelMixin 详情视图扩展类 -- Retrieve
# 源码
class RetrieveModelMixin(object):
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
# 2.3 CreateModelMixin 创建视图扩展类 -- Create
# 源码
class CreateModelMixin(object):
"""
Create a model instance.
"""
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
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 {}
2.4 UpdateModelMixin 更新视图扩展类
2.5 DestoryModelMixin 删除视图扩展类
[/code]

可以看出Mixin扩展类中主要实现了调用查询集,序列化器做相应的序列化或者反序列化。所以依赖GenericAPIView提供的指定查询集和序列化器的方法,同时GenericAPIView也依赖于Mixin扩展类提供的action方法实现响应的功能,所以类视图结合两者就产生了。

3、五个扩展类 + GenericAPIView ==> 类视图

只需要指定查询集和序列化器

# 3.1 ListAPIView
# 源码
class ListAPIView(mixins.ListModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
# 3.2	RetrieveAPIView
# 源码
class RetrieveAPIView(mixins.RetrieveModelMixin,
GenericAPIView):
"""
Concrete view for retrieving a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
# 3.3	CreateAPIView
# 源码
class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for creating a model instance.
"""
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
# 3.4 UpdateAPIView
...
# 3.5 DestoryAPIView
...
# 3.6 RetrieveUpdateAPIView
class RetrieveUpdateAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating a model instance.
"""
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 patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
3.7 RetrieveUpdataDestoryAPIView
...
[/code]

综上:最后通过封装得到的ListAPIVIew/RetrieveAPIView/UpdateAPIView/DestroyAPIView/CreateAPIView作为我们常用的API接口基类。思考:我们到此仅仅每个API类中只有一种操作,要么List要么Create,有没有一个定义多种操作的类呢?肯定有的下一篇的视图集应运而生。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: