一 两个视图基类
1.1 APIView
APIView是所有REST framework提供的所有试图的基类,继承Django的View类。
1.2 GenericAPIView(通用视图类)
类属性: queryset = None serializer_class = None lookup_field = ‘pk’(是get_object方法查询对象时的条件,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(过滤相关) paginate_queryset(分页相关)
1.3 基于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()
1.4 基于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('')
练习
1 使用GenericAPIView写出book的5个接口
class BookView(GenericAPIView):
serializer_class = BookSerializers
queryset = User.objects.all()
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 Book2View(GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializers
def get(self, request):
obj = self.get_object()
ser = self.get_serializer(instance=obj)
return Response(ser.data)
def put(self, request, pk):
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('')
2 使用面向对象,写5个父类, 继承GenericAPIView+某几个父类后,就有某几个接口 新增1条 GenericAPIView+Create
class GetAll:
def get(self, request):
print(self.__dict__)
queryset = self.get_queryset()
ser = self.get_serializer(instance=queryset, many=True)
return Response(ser.data)
class GetOne:
def get(self, request, pk):
obj = self.get_object()
ser = self.get_serializer(instance=obj)
return Response(ser.data)
class Create:
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 Alter:
def put(self, request, pk):
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)
class Delete:
def delete(self, request, pk):
self.get_queryset().filter(pk=pk).delete()
return Response()
class BookView(GenericAPIView, GetAll, Create):
queryset = Book.objects.all()
serializer_class = BookSerializers
class Book2View(GenericAPIView, GetOne, Alter, Delete):
queryset = Book.objects.all()
serializer_class = BookSerializers
3 9个视图子类
class GetAll(GenericAPIView):
def get(self, request):
print(self.__dict__)
queryset = self.get_queryset()
ser = self.get_serializer(instance=queryset, many=True)
return Response(ser.data)
class GetOne(GenericAPIView):
def get(self, request, pk):
obj = self.get_object()
ser = self.get_serializer(instance=obj)
return Response(ser.data)
class Create(GenericAPIView):
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 Alter(GenericAPIView):
def put(self, request, pk):
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)
class Delete(GenericAPIView):
def delete(self, request, pk):
self.get_queryset().filter(pk=pk).delete()
return Response()
class A(GetAll):
pass
class B(Create):
pass
class C(GetOne):
pass
class D(Alter):
pass
class E(Delete):
pass
class F(GetAll, Create):
pass
class G(GetOne, Alter):
pass
class H(Alter, Delete):
pass
class J(Delete):
pass
class I(GetOne, Alter, Delete):
pass
class BookView(A):
queryset = Book.objects.all()
serializer_class = BookSerializers
class Book2View(G):
queryset = Book.objects.all()
serializer_class = BookSerializers
二 五个视图扩展类
2.1 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)
2.2 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 {}
2.3 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)
2.4 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):
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)
2.5 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()
2.6 基于GenericAPIView和五个视图扩展类写接口
因为五个视图扩展类用到了GenericAPIView类中的属性和方法,所以必须结合GenericAPIView一起使用。
需要什么功能就继承GenericAPIView和试图扩展类
from rest_framework.Mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
class UserView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = User.objects
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
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
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 CreateAPIView
class CreateAPIView(mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset.
"""
def get(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
3.3 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.4 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)
3.5 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)
3.6 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)
3.7 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.8 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)
3.9 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)
3.10 基于九个视图子类写接口
class UserView(ListAPIView):
queryset = User.objects
serializer_class = UserSerializers
class User2View(RetrieveAPIView):
queryset = User.objects
serializer_class = UserSerializers
四 视图集
4.1 ViewsetMixin
重写了as_view方法,只要继承了ViewsetMixin就必须在as_view中传actions参数,以字典的形式,key值是请求方式,value是方法名。
class ViewSetMixin:
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
if not actions:
raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`")
def view(request, *args, **kwargs):
for method, action in actions.items():
handler = getattr(self, action)
self.get = 视图基类的list方法
setattr(self, method, handler)
return self.dispatch(request, *args, **kwargs)
return csrf_exempt(view)
4.2 ViewSet
继承了ViewSetMixin和APIView
class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass
4.3 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
4.3 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
4.4 ReadOnlyModelViewSet
继承了ListModelMixin、RetrieveModelMixin和GenericViewSet
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
pass
4.5 基于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'})),
继承关系图
|