目录
视图
APIView
APIView与View的不同之处:
GenericAPIView[通用视图类]
类属性
类方法
基于APIView写五个接口
基于GenericAPIVIew写5个接口
五个视图扩展类
ListModelMixin
CreateModelMixin
RetrieveModelMixin
UpdateModelMixin
DestroyModelMixin
基于GenericAPIView和五个视图扩展类写接口
九个视图子类
ListAPIView
CreateAPIView
RetrieveAPIView
UpdateAPIView
DestroyAPIView
ListCreateAPIView
RetrieveUpdateAPIView
RetrieveDestroyAPIView
RetrieveUpdateDestroyAPIView
基于九个视图子类写接口
视图集
ViewsetMixin
ViewSet
GenericViewSet
ModelViewSet
ReadOnlyModelViewSet
基于ModelViewSet写接口
图实
Django REST framwork 提供的视图的主要作用:
- 控制序列化器的执行(检验、保存、转换数据)
- 控制数据库查询的执行
视图
REST framework 提供了众多的通用视图基类与扩展类,以简化视图的编写。
APIView
rest_framework.views.APIView
APIView
是REST framework提供的所有视图的基类,继承自Django的View
父类。
APIView
与View
的不同之处:
- 传入到视图方法中的是REST framework的
Request
对象,而不是Django的HttpRequeset
对象;
- 视图方法可以返回REST framework的
Response
对象,视图会为响应数据设置(render)符合前端要求的格式;
- 任何
APIException
异常都会被捕获到,并且处理成合适的响应信息;
- 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
GenericAPIView[通用视图类]
rest_framework.generics.GenericAPIView
继承自APIVIew
,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持。通常在使用时,可搭配一个或多个Mixin扩展类。
方法 |
作用 |
self.get_object() |
根据pk获取单个数据 |
self.get_serializer() |
获取要使用的序列化类 |
self.get_queryset() |
获取所有要序列化的数据 |
类属性
queryset = None
serializer_class = None
lookup_field = 'pk'【是get_obj方法拆寻对象是的条件, key=value的形式, key是lookup_field的值,value是路由匹配中的又名分组捉着转换器】
filter_backends 【用于queryset过来的filter后端类】
pagination_class 【分页类】
类方法
get_queryset() 获取所有要序列化的数据
get_object() 根据pk获取单个数据
get_serializer() 获取要使用的序列化器, 直接使用【调用了get_serializer_class并加括号】
get_serializer_class 【return self.serializer_class , 拿到的是序列化类】
filter_queryset() 【过滤相关】
pagination_queryset【分页相关】
基于APIView写五个接口
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from .serializers import UserSerializers
from .models import User
from rest_framework.response import Response
class UserView(APIView):
def get(self, request):
query_set = User.objects.all()
ser = UserSerializers(instance=query_set, many=True)
return Response(ser.data)
def post(self, request):
ser = UserSerializers(data=request.data)
if ser.is_valid():
return Response(ser.data)
return Response(ser.errors)
class User2View(APIView):
def get(self, request, pk):
obj = User.objects.filter(pk=pk).first()
ser = UserSerializers(instance=obj)
return Response(ser.data)
def put(self, request, pk):
obj = User.objects.filter(pk=pk).first()
ser = UserSerializers(instance=obj, data=request.data)
if ser.is_valid():
return Response(ser.data)
return Response(ser.errors)
def delete(self, request, pk):
User.objects.filter(pk=pk).delete()
return Response()
基于GenericAPIVIew写5个接口
class UserView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializers
def get(self, request):
queryset = self.get_queryset()
ser = self.get_serializer(instance=queryset, many=True)
return Response(ser.data)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
return Response(ser.errors)
class User2View(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializers
def get(self, request):
obj = self.get_object()
ser = self.get_serializer(instance=obj)
return Response(ser.data)
def put(self, request):
obj = self.get_object()
ser = self.get_serializer(instance=obj, data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
return Response(ser.errors)
def delete(self, request, pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')
五个视图扩展类
ListModelMixin
类中有一个list方法, 就是上面基于GenericAPIView写的五个接口中的get获取全部
class ListModelMixin:
"""
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)
CreateModelMixin
类中有一个create方法,就是上面写的基于GenericAPIView写的五个接口中的post
class CreateModelMixin:
"""
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 {}
RetrieveModelMixin
类中有一个retrieve方法,就是上边写的基于GenericAPIView写的get方法获取单条数据。
class RetrieveModelMixin:
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
UpdateModelMixin
类中有一个update方法,就是上边写的基于GenericAPIView写的put方法修改一条数据。
class UpdateModelMixin:
"""
Update a model instance.
"""
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
return Response(serializer.data)
def perform_update(self, serializer):
serializer.save()
def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)
DestroyModelMixin
类中有一个destroy方法,就是上边写的基于GenericAPIView写的delete方法。
class DestroyModelMixin:
"""
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()
基于GenericAPIView和五个视图扩展类写接口
因为五个视图扩展类用到了GenericAPIView类中的属性和方法,所以必须结合GenericAPIView一起使用。
需要什么功能就继承GenericAPIView和试图扩展类
from rest_framework.Mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
class UserView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = User.objects # 可以加.all(),也可以不用加,get_queryset方法会自动加
serializer_class = UserSerializers
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 User2View(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
queryset = User.objects # 可以加.all(),也可以不用加,get_queryset方法会自动加
serializer_class = UserSerializers
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)
九个视图子类
from rest_framework.generics import ListAPIView, CreateAPIView, RetrieveAPIView, UpdateAPIView, DestroyAPIView, \
ListCreateAPIView, RetrieveUpdateDestroyAPIView, RetrieveUpdateAPIView, RetrieveDestroyAPIView
ListAPIView
class ListAPIView(mixins.ListModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
CreateAPIView
class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
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)
UpdateAPIView
class UpdateAPIView(mixins.UpdateModelMixin,
GenericAPIView):
"""
Concrete view for updating a model instance.
"""
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)
DestroyAPIView
class DestroyAPIView(mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for deleting a model instance.
"""
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
ListCreateAPIView
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset or creating a model instance.
"""
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
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)
RetrieveDestroyAPIView
class RetrieveDestroyAPIView(mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving or deleting a model instance.
"""
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
RetrieveUpdateDestroyAPIView
class RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView):
"""
Concrete view for retrieving, updating or deleting 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)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
基于九个视图子类写接口
class UserView(ListAPIView):
queryset = User.objects
serializer_class = UserSerializers
class User2View(RetrieveAPIView):
queryset = User.objects
serializer_class = UserSerializers
视图集
ViewsetMixin
重写了as_view方法,只要继承了ViewsetMixin就必须在as_view中传actions参数,以字典的形式,key值是请求方式,value是方法名。
class ViewSetMixin:
@classonlymethod
# ViewsetMixin的as_view
def as_view(cls, actions=None, **initkwargs):
# actions参数不能为空
# actions = {'get': 'list', 'post':'create'}
if not actions:
raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`")
# 当路由匹配成功会执行view
def view(request, *args, **kwargs):
# method = get
# action = list
for method, action in actions.items():
# 反射 视图类的对象找'list'方法
# 如果继承了五个视图基类 就可以找到list方法
handler = getattr(self, action)
# 给对象设置属性
self.get = 视图基类的list方法
setattr(self, method, handler)
# 执行dispatch 是APIView里的dispatch
return self.dispatch(request, *args, **kwargs)
return csrf_exempt(view)
ViewSet
继承了ViewSetMixin和APIView
class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass
GenericViewSet
继承了ViewSetMixin和GenericAPIView
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
ModelViewSet
继承了五个视图扩展类和GenericViewSet
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
ReadOnlyModelViewSet
继承了ListModelMixin、RetrieveModelMixin和GenericViewSet
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
pass
基于ModelViewSet写接口
from rest_framework.viewsets import ViewSetMixin, ViewSet, GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
class UserView(ModelViewSet):
queryset = User.objects
serializer_class = UserSerializers
路由必须传actions参数
path('users/', views.UserView.as_view({'get': 'list', 'post':'create'})),
path('users/<int:pk>/', views.UserView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
图实
GenericaAPIVIew
五个视图