django 3.2.13

在进行下面的操作之前切记在setting.py里面注册rest_framework

一、视图

重点:请先认真读完下面的内容再进行深入学习,或者先跳过当有不懂的时候,回头再看看下面的话


视图包括下面一会介绍的视图集知识点,都是由繁琐简单,最后只需几行就可实现复杂功能(此类功能大多为死板的增删改查,不够灵活),重点就在互相之间的继承,通过前面学习繁琐的代码就能逐步知其然知其所以然,并且利于自己实现特别的需求

RESTful接口规范:为什么要先说这个呢?因为Django REST基于RESTful接口规范来实现的功能。RESTful接口规范指出,要根据不同的需求对应不同的请求方式,比如查询使用GET删除使用DELETE增加使用POST
固定模式(Django rest也会用到):
GET 127.0.0.1/products :将返回所有产品清单
GET 127.0.0.1/products/4 :将获取产品 pk值=4
POST 127.0.0.1/products :将产品新建到集合
PUT 127.0.0.1/products/4 :将更新产品 pk值=4
DELETE 127.0.0.1/products/4 :将删除 pk值=4的产品
特别的需求
PUT 127.0.0.1/products/4/news :这个与上面不同就是4后面加了个news,这个news就属于自己定义的,其意思可以为将 pk值为4的商品的某项功能更新(与上面不同就是这里"更新"属于自己特殊需求写的代码

pycharm debug:为了方便了解继承关系

python增删改查方法封装类_restful


python增删改查方法封装类_python增删改查方法封装类_02


python增删改查方法封装类_python_03

1.APIView

Request与HttpRequeset区别:Request的request.data属性即可获取表单类型数据或者JSON数据,无需HttpRequeset这么麻烦;Request的request.query_params等同于HttpRequeset里面的request.GET

注意:使用APIView与SessionAuthentication会产生csrf的问题,为了解决此问题,注释掉'django.middleware.csrf.CsrfViewMiddleware',没有效果,需要写入下面的代码

from rest_framework.authentication import SessionAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        return
class MyView(APIView):
    authentication_classes = (CsrfExemptSessionAuthentication,)

导入:from rest_framework.views import APIView

介绍:APIViewREST framework提供的所有视图的基类,故其并不常用,了解它的用法便于对后面内容的理解,继承自Django的View父类,其大体与View用法一样,但有些不同下面马上会介绍。

不同

  1. 传入到视图方法中的是REST framework封装好的Request对象,而不是Django的HttpRequeset对象(前言里面介绍了他们的一点区别)
  2. 视图方法可以返回REST framework的Response对象,不使用之前文章的类似HttpResponse等,直接用一个Response对象就能适合的返回前端需要的数据
  3. 在进行dispatch()分发前,会对请求进行身份认证权限检查流量控制

关系图谱:

python增删改查方法封装类_django_04


urls.py

urlpatterns = [
        path("teacher", views.TestAPIView.as_view())
]

views.py

from rest_framework.views import APIView
from .models import Student, Teacher
from .serializers import StudentSerializer
from rest_framework.response import Response
class TestAPIView(APIView):
	# get请求会这个
    def get(self, request):
        data = Student.objects.all() 
        serializer = StudentSerializer(instance=data, many=True)
        return Response(serializer.data)

2.GenericAPIView

导入:from rest_framework.generics import GenericAPIView

介绍:继承自APIVIew,其与APIVIew一样属于基础类,并不常用,常常配合下面的扩展使用,增加了对于列表视图(就是获取表单全部数据)和详情视图(表单具体数据)可能用到的通用支持方法。通常使用时,可搭配一个或多个Mixin扩展

关系图谱:

python增删改查方法封装类_django_05

代码分析:

  1. 获取全部
    path("teachers", views.TestGenericAPIView.as_view())
class TestGenericAPIView(GenericAPIView):
    queryset = Student.objects.all() 
    ''' 
    GenericAPIView里面设置了queryset ,
    其会在GenericAPIView的get_queryset()函数里面调用
    '''
    serializer_class = StudentSerializer
    ''' 
    GenericAPIView里面设置了serializer_class ,
    其会在GenericAPIView的get_queryset()函数里面调用
    '''
    def get(self, request):
        book = self.get_queryset()
    ''' 
    get_queryset属于父类GenericAPIView里面的函数
    其用法比较简单,含义≈data = Student.objects.all()
    注意重点起到校验检查的作用
    '''
        serializer = self.get_serializer(book, many=True)
    ''' 
    get_serializer属于父类GenericAPIView里面的函数
    其主要是为serializer添加了一个context属性request、format、view
    这三个数据对象可以在定义序列化器时使用
    效果≈serializer = StudentSerializer(instance=data, many=True,context=)
    
    '''
        return Response(serializer.data)
  1. 获取单个
    path("teachers/<pk>", views.TestGenericAPIView.as_view()) #pk表示主键如果其它字段设置可名就可以
class TestGenericAPIView(GenericAPIView):
    queryset = Student.objects.all()

    serializer_class = StudentSerializer

    def get(self, request, pk):
        book = self.get_object()
   ''' 
   注意:get(self, request, pk)中参数pk是必填的必须这样写的,其在GenericAPIView被写死
   get_object()起初通过源码"queryset = self.filter_queryset(self.get_queryset())",
   获取验证并获取A=Student.objects.all()对象,但不要以为它向服务器发送获取全部数据的请求,
   因为下面"obj = get_object_or_404(queryset, **filter_kwargs)"会发送类似A.get(id=pk)
   的请求(A是Student.objects.all()),django会发送最终的请求(即不用不发)
   '''
        serializer = self.get_serializer(book)
        return Response(serializer.data)

二、扩展类

这几个扩展类都是基于GenericAPIView的扩展

关系图谱:

python增删改查方法封装类_django_06

1. ListModelMixin

导入:from rest_framework.mixins import ListModelMixin

介绍:属于获取全部的简写,其依赖于继承GenericAPIView(必须与其一起被其它程序继承),其属于是一个整合,没有实际的基础代码

代码分析:

path("teachers", views.TestGenericAPIView.as_view())

class TestGenericAPIView(ListModelMixin,GenericAPIView):
    queryset = Teacher.objects.all()

    serializer_class = TeacherSerializer

    def get(self, request):
        return self.list(request)
   # ListModelMixin里面的一个函数叫做list(),其实现功能与我刚刚上面才单继承GenericAPIView写的大同小异

2. RetrieveModelMixin

导入:from rest_framework.mixins import RetrieveModelMixin

介绍:属于获取单个的简写,其属于是一个整合

代码:

path("teachers/<pk>", views.TestGenericAPIView.as_view()) #pk表示主键如果其它字段设置可名就可以

class TestGenericAPIView(RetrieveModelMixin, GenericAPIView):
    queryset = Teacher.objects.all()

    serializer_class = TeacherSerializer

    def get(self, request, pk):
        return self.retrieve(request)

3. CreateModelMixin

导入:from rest_framework.mixins import CreateModelMixin

介绍:属于创建的简写,其属于是一个整合

代码分析:

path("teachers/<pk>", views.TestGenericAPIView.as_view())

class TestGenericAPIView(CreateModelMixin, GenericAPIView):
    queryset = Teacher.objects.all()

    serializer_class = TeacherSerializer
    
    def post(self, request, pk):
        return self.create(request)
   # 来自CreateModelMixin的create(),里面使用上一篇文章序列化里面新增的知识

4. UpdateModelMixin

导入:from rest_framework.mixins import UpdateModelMixin

介绍:属于创建的简写,其属于是一个整合

代码分析:

path("teachers", views.TestGenericAPIView.as_view())path("teachers/<pk>", views.TestGenericAPIView.as_view())

class TestGenericAPIView(RetrieveModelMixin, UpdateModelMixin, GenericAPIView):
    queryset = Student.objects.all()

    serializer_class = StudentSerializer

    def get(self, request, pk):
        return self.retrieve(request)

    # def put(self, request, pk):
    #     return self.update(request) # 全部更新
    
	# 使用update时,如果在序列化时没有专门设置,名称属性required=False,默认就需要提供全部数据才能进行更新
    def put(self, request, pk):
        return self.partial_update(request) # 局部更新
   # 使用partial_update时,如果在序列化时没有专门设置,名称属性required=False,也可以提供部分值就能成功更新数据,原理是:使用partial_update在UpdateModelMixin里面partial的参数为true;而update是false

5. DestroyModelMixin

导入:from rest_framework.mixins import DestroyModelMixin

介绍:属于删除的简写,其属于是一个整合

代码:

path("teachers", views.TestGenericAPIView.as_view())path("teachers/<pk>", views.TestGenericAPIView.as_view())

class TestGenericAPIView(RetrieveModelMixin, DestroyModelMixin, GenericAPIView):
    queryset = Student.objects.all()

    serializer_class = StudentSerializer

    def get(self, request, pk):
        return self.retrieve(request)

    def delete(self, request, pk):
        return self.destroy(request)

三、扩展类的子类

同二、三一样,只是相当于对它们的简写,继承简写,也无需写get、post之类

1.CreateAPIView

导入:from rest_framework.generics import CreateAPIView

解释:用来创建,继承+post,其继承GenericAPIView, CreateModelMixin

class TestGenericAPIView(CreateAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
# 这样就实现了上面介绍CreateModelMixind的功能

2.ListAPIView

导入:from rest_framework.generics import ListAPIView

解释:用来查全部,继承+get,其继承GenericAPIView、ListModelMixin

class TestGenericAPIView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
# 这样就实现了上面介绍ListModelMixin的功能

3.RetrieveAPIView

导入:from rest_framework.generics import RetrieveAPIView

解释:用来查单个,继承+get,其继承GenericAPIView、RetrieveModelMixin

class TestGenericAPIView(RetrieveAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
# 这样就实现了上面介绍RetrieveModelMixin的功能

4.DestroyAPIView

导入:from rest_framework.generics import DestroyAPIView

解释:用来删除单个,继承+delete ,其继承GenericAPIView、DestroyModelMixin

class TestGenericAPIView(DestroyAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
# 这样就实现了上面介绍DestoryModelMixin的功能

5.UpdateAPIView

导入:from rest_framework.generics import UpdateAPIView

解释:用来修改,继承+put(改全部)+patch(改单个) ,其继承GenericAPIView、UpdateModelMixin

class TestGenericAPIView(UpdateAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
# 这样就实现了上面介绍UpdateModelMixin的功能

6. RetrieveUpdateAPIView

解释:提供 get、put、patch方法

7. RetrieveUpdateDestroyAPIView

解释:提供 get、put、patch、delete方法

四、视图集

解释:视图集提供下面五种方式,具体能用什么,看你继承什么,与需要,配合url填入

  1. list() 提供一组数据
  2. retrieve() 提供单个数据
  3. create() 创建数据
  4. update() 保存数据
  5. destroy() 删除数据

1. ViewSet

导入:from rest_framework.viewsets import ViewSet

说明:其先继承了ViewSetMixin再继承APIView,ViewSetMixin相当于重写的APIView的as_view分发请求(其可以把请求与自己定义的函数名结合起来),其为基础类

path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
        path("teachers/<pk>", views.TestGenericAPIView.as_view({'get':'retrieve'}))
class TestGenericAPIView(ViewSet):
	
	'''
	其不使用get(),post()方法
	但是它通过ViewSetMixin的as_view()提供的参数(在ViewSetMixin为actions),根据对应关系创建了get,put,delete等请求
	然后其发送给APIView的dispatch去类似于扩展类一样去分发给get、post、delete等等
	'''
    def list(self, request):
        data = Student.objects.all()
        serializer = StudentSerializer(instance=data,many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk):
        data = Student.objects.all().get(id=pk)
        serializer = StudentSerializer(instance=data)
        return Response(serializer.data)

2. GenericViewSet

导入:from rest_framework.viewsets import GenericViewSet

说明:其先继承了ViewSetMixin再继承GenericAPIView,重点提供get_objectget_queryset等属性与方法,所以较为基础类

path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
        path("teachers/<pk>", views.TestGenericAPIView.as_view({'get':'retrieve'}))
class TestGenericAPIView(GenericViewSet):

    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    def list(self, request):
        data = self.get_queryset()
        serializer = self.get_serializer(data,many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk):
        data = self.get_object()
        serializer = self.get_serializer(data)
        return Response(serializer.data)

3.ModelViewSet

导入:from rest_framework.viewsets import ModelViewSet

说明:继承自GenericViewSet,同时包括了ListModelMixinRetrieveModelMixinCreateModelMixinUpdateModelMixinDestoryModelMixin

path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
        path("teachers/<pk>", views.TestGenericAPIView.as_view({'get':'retrieve', 'delete':'destroy'}))
class TestGenericAPIView(ModelViewSet):

    queryset = Student.objects.all()
    serializer_class = StudentSerializer

4.ReadOnlyModelViewSet

导入:from rest_framework.viewsets import ReadOnlyModelViewSet 说明:继承自GenericViewSet,同时包括了ListModelMixinRetrieveModelMixin,用来获取数据

path("teachers", views.TestGenericAPIView.as_view({'get':'list'})),
        path("teachers/<pk>", views.TestGenericAPIView.as_view({'get':'retrieve'})) #pk表示主键如果其它字段设置可名就可以
class TestGenericAPIView(ReadOnlyModelViewSet):

    queryset = Student.objects.all()
    serializer_class = StudentSerializer
	# 只读只剩下list()和retrieve()方法了

5. 自定义

path("teachers/lastsome", views.TestGenericAPIView.as_view({'get':'lastsome'})),
class TestGenericAPIView(ReadOnlyModelViewSet):

    queryset = Student.objects.all()
    serializer_class = StudentSerializer

    def lastsome(self, request):

        data = Student.objects.get(id=7)
        serializer = StudentSerializer(instance=data)
        a = serializer.data
        a.pop('time')
        return Response(a)