Django REST framework中GenericAPIView与混入扩展类详解

简介: Django REST framework中GenericAPIView与混入扩展类详解

前言

    主要介绍了Django REST framework中,GenericAPIView的与混入类、扩展类的概念、功能和使用方法,最后通过代码示例逐步演示了从GenericAPIView到GenericAPIView结合混入类再到扩展类、视图集的封装流程及其操作。


一、GenericAPIView

1. GenericAPIView是什么

GenericAPIView 继承自 APIVIew,增加了对于 列表视图详情视图 可能用到的 通用支持方法,通常使用时,可搭配一个或多个Mixin扩展类,来实现其他更加高级的功能,总结来说 GenericAPIView 是有关数据管理的基类,未来还会学习有关方法操作的基类

导入GenericAPIView: from rest_framework.generics import GenericAPIView

2. GenericAPIView内部属性

🔥列表、详情视图通用属性:

  • queryset=objects.all/.filter/.order_by
  • 列表视图要操作的查询结果对象
  • serializer_class=Serializer
  • 视图中会使用到的 序列化器,一般都是针对于上一个 queryset 所指定的

列表视图单独属性:

  • pagination_class
  • 分页控制类,进行分页设置
  • filter_backends
  • 过滤控制后端,可以对数据进行字段过滤

🔥详情页视图单独属性:

  • lookup_url_kwarg
  • 动态路由传递的参数命名
  • lookup_field
  • 过滤的orm参数

🔥列表与详情视图通用方法:

  • get_queryset(self)
  • 返回视图使用的查询集,是列表视图与详情视图获取数据的基础
  • 默认返回queryset属性,支持重写
  • get_serializer_class(self)
  • 返回序列化器类,默认返回serializer_class,可以重写
  • get_serializer(self, args, kwargs)
  • 返回序列化器对象

🔥详情页视图单独方法:

  • get_object(self)
  • 返回详情视图所需的模型类数据对象,默认使用lookup_field参数来过滤queryset。 在试图中可以调用该方法获取详情信息的模型类对象
  • 若详情访问的模型类对象不存在,会返回404,如果访问到多个重复,也会报错,默认使用get方法进行orm查询
  • 该方法会默认使用 APIView 提供的check_object_permissions方法检查当前对象是否有权限被访问

3. GenericAPIView增删改查

1. 获取数据与添加数据:

编写UserGenView视图类,urls.py路由,代码如下:

# views.py
from rest_framework.response import Response
from app.models import UserModel
from app.serializer.userSerializer import UserSerializer
from rest_framework.generics import GenericAPIView
class UserGenView(GenericAPIView):
    queryset = UserModel.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'pk'
    lookup_url_kwarg = 'id'
    def get(self, request):
        users = self.get_queryset() # <==> UserModel.objects.all()
        ser = self.get_serializer(instance=users, many=True)
        return Response({"userList": ser.data})
    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            print("校验成功!")
            ser.save()
            return Response({"user": ser.data})
        else:
            return Response({"error": ser.errors})
#--------------------------------------------------------------
#urls.py
from django.urls import path
from app.views import UserView,UserIdView,UserGenView,UserGenIDView
urlpatterns = [
    path('user/', UserView.as_view()),
    path('user/<int:id>/', UserIdView.as_view()),
    path('usgns/', UserGenView.as_view()),
]

2. GenericAPIView 增删改查 (传id)

UserGenIDView模型类和urls.py路由 代码如下:

#views.py
from rest_framework.response import Response
from app.models import UserModel
from app.serializer.userSerializer import UserSerializer
from rest_framework.generics import GenericAPIView
# Create your views here.
class UserGenIDView(GenericAPIView):
    queryset = UserModel.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'pk'  #指向数据库,查询key
    lookup_url_kwarg = 'id' # url 路径中的参数名
    def get(self, request, id):
        user = self.get_object()
        ser = self.get_serializer(instance=user)
        return Response({"message": "查询成功!","data":ser.data})
    def put(self, request, id):
        user = self.get_object()
        ser = self.get_serializer(instance=user, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({"message": "success"})
        else:
            return Response({"message": ser.errors})
    def delete(self, request, id):
        self.get_object().delete()
        return Response({"message":"删除成功!"})
#-------------------------------------------------
#urls.py
from django.urls import path
from app.views import UserView,UserIdView,UserGenView,UserGenIDView
urlpatterns = [
    path('user/', UserView.as_view()),
    path('user/<int:id>/', UserIdView.as_view()),
    path('usgns/', UserGenView.as_view()),
    path('usgns/<int:id>/', UserGenIDView.as_view()),
    
]

二、混入类与扩展类

Django REST framework (DRF) 中,混入扩展类(Mixin Extension Classes)是一种特殊的类,它们封装了特定功能的代码片段,这些功能通常与数据库操作(如增删改查)相关。混入扩展类(通常称为 Mixin 类)不是独立的视图类,而是用于与通用视图基类(如 GenericAPIView)结合使用,以提供额外的功能。

GenericAPIView 只是提供了数据,对应的访问功能是没有实现的,所以DRF还有五个提供方法的混入类,可以完成基本增删改查功能,我们也叫Mixin 混入类,通过GenericAPIView与混入类的多继承,可以实现更加复杂的接口功能,GenericAPIView提供数据,而混入类提供操作

导包: from rest_framework.mixins import CreateModelMixin,ListModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin

1. 混入类的功能划分

1. ListModelMixin

  • 列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图
  • 默认返回200状态码
  • Mixin的 list 方法会对数据进行过滤和分页

2. CreateModelMixin

  • 创建视图扩展类,提供create(request, *args, **kwargs)方法快速实现创建资源的视图
  • 成功返回201状态码。
  • 如果序列化器对前端发送的数据验证失败返回 400错误

3. RetrieveModelMixin

  • 详情视图扩展类,提供retrieve(request, *args, **kwargs)方法进行单独数据的返回
  • 如果详情数据存在,返回200, 否则返回404

4. UpdateModelMixin

  • 更新视图扩展类,提供update(request, *args, **kwargs)方法
  • 同时提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。
  • 成功返回200序列化器校验数据失败时,返回400错误

5. DestroyModelMixin

  • 删除视图扩展类,提供destroy(request, *args, **kwargs)方法
  • 可以快速实现删除一个存在的数据对象
  • 成功返回204,不存在返回404

2. 混入类与GenericAPIView的组合使用(增删改查操作)

查询所有,增加数据,(未传 参数 id)代码示例如下:

# views_mixin.py
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from app.models import UserModel
from app.serializer.userSerializer import UserSerializer
from rest_framework.mixins import ListModelMixin,CreateModelMixin
class UserMixinView(GenericAPIView, ListModelMixin,CreateModelMixin):
    # GenericAPIView 对数据提供进行了封装
    queryset = UserModel.objects.all()
    serializer_class = UserSerializer
    def get(self, request):
        # PS:可以点进ListModelMixin中与list()方法对比,list()方法已经对下面两行代码实现过封装了
        # 获取所有信息,并进行序列化返回
        # users = self.get_queryset()
        # ser = self.get_serializer(instance=users, many=True)
        # return Response({"message":"Hello GET","data":ser.data})
        return self.list(request)
    def post(self, request):
        # PS:可以点进CreateModelMixin中与create()方法对比,
        # create()方法已经对手动使用post方法新增数据封装过了
        return self.create(request)

查,改,删(传参数 id),代码示例如下:

# views_mixin.py
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from app.models import UserModel
from app.serializer.userSerializer import UserSerializer
from rest_framework.mixins import RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
class UserMixinIDView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
    # GenericAPIView 对数据提供进行了封装
    queryset = UserModel.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'pk'
    lookup_url_kwarg = 'id'
    def get(self, request, id):
        return self.retrieve(request)
    def put(self, request, id):
        return self.update(request)
    def delete(self, request, id):
        return self.destroy(request)

urls.py:

from django.urls import path
from app.views_mixin import UserMixinView,UserMixinIDView
urlpatterns = [
    path('usmixin/', UserMixinView.as_view()),
    path('usmixin/<int:id>', UserMixinIDView.as_view()),
]

3. 视图扩展类的应用

Django REST framework (DRF) 中,视图扩展类(View Extensions or Generic View Classes)是一组内置的类,它们为构建 RESTful API 提供了强大的基础。这些扩展类允许开发者以声明式的方式定义视图的行为,从而简化了 API 开发的复杂性。

这些类结合了 Mixin 类的功能,并提供了额外的逻辑(如请求处理、权限检查、序列化等)。通用视图类可以直接作为 API 视图使用。

一些常见的通用视图类包括:

  • ListAPIView:列出查询集中的对象。
  • CreateAPIView:创建并保存一个模型实例。
  • RetrieveAPIView:根据提供的查找字段检索并返回对象。
  • UpdateAPIView:更新一个现有的模型实例。
  • DestroyAPIView:删除一个现有的模型实例。

1. ListAPIView

  • 提供get方法,可以获取多条数据

继承自:GenericAPIViewListModelMixin

class TeacherListView(ListAPIView):
    queryset = Teacher.objects.all()  # 你要序列化的哪些数据结果
    serializer_class = TeacherListSer  # 用什么序列化器

2. CreateAPIView

  • 提供post方法,可以创建一条数据

继承自:GenericAPIViewCreateModelMixin

class TeacherCreateView(CreateAPIView):
    serializer_class = TeacherCreateSer

3. RetireveAPIView

  • 提供get方法,获取某个具体数据的详情

继承自:GenericAPIViewRetrieveModelMixin

class TeacherDetailView(RetrieveAPIView):
    lookup_field = 'pk'  # 数据库里的字段
    lookup_url_kwarg = 'id'  # 过滤字段的条件,从路由传参数过来的
    queryset = Teacher.objects.all()
    serializer_class = TeacherDetailSer

4. UpdateAPIView

  • 提供 put 和 patch 方法,可以更新或者局部更新某条数据

继承自:GenericAPIViewUpdateModelMixin

class TeacherUpdateView(UpdateAPIView):
    lookup_field = 'pk'  # 数据库里的字段
    lookup_url_kwarg = 'id'  # 过滤字段的条件,从路由传参数过来的
    queryset = Teacher.objects.all()
    serializer_class = TeacherUpdateSer

5. DestoryAPIView

  • 提供 delete 方法,可以删除某条存在数据

继承自:GenericAPIViewDestoryModelMixin

class TeacherDestoryView(DestroyAPIView):
    lookup_field = 'pk'  # 数据库里的字段
    lookup_url_kwarg = 'id'  # 过滤字段的条件,从路由传参数过来的
    queryset = Teacher.objects.all()

6. ListCreateAPIView

  • 提供 post 和 get 方法,可以创建一条数据,或获取列表数据

继承自:GenericAPIViewCreateModelMixinListModelMixin

class TeacherListCreateView(ListCreateAPIView):
    queryset = Teacher.objects.all()
    serializer_class = TeacherListCreateSer 
    # 共用一个序列化器同时实现创建和数据展示

7. RetrieveUpdateAPIView

  • 提供 get、put、patch 方法,可以获取一条数据详情,也可以更新一条数据

继承自:GenericAPIViewRetrieveModelMixinUpdateModelMixin

class TeacherRetrieveUpdateView(RetrieveUpdateAPIView):
    lookup_field = 'pk'  # 数据库里的字段
    lookup_url_kwarg = 'id'  # 过滤字段的条件,从路由传参数过来的
    queryset = Teacher.objects.all()
    serializer_class = TeacherRetrieveUpdateSer

8. RetrieveDestroyAPIView

  • 提供 get 和 delete 方法,可以获取和删除一条已存在数据

继承自:GenericAPIViewRetrieveModelMixinDestoryModelMixin

class TeacherRetrieveDestroyView(RetrieveDestroyAPIView):
    lookup_field = 'pk'  # 数据库里的字段
    lookup_url_kwarg = 'id'  # 过滤字段的条件,从路由传参数过来的
    queryset = Teacher.objects.all()
    serializer_class = TeacherDeatilSer 

9. RetrieveUpdateDestoryAPIView

  • 提供 get、put、patch、delete 方法,啥也能干

继承自:GenericAPIViewRetrieveModelMixinUpdateModelMixinDestoryModelMixin

class TeacherAll(RetrieveUpdateDestroyAPIView):
    lookup_field = 'pk'  # 数据库里的字段
    lookup_url_kwarg = 'id'  # 过滤字段的条件,从路由传参数过来的
    queryset = Teacher.objects.all()
    serializer_class = TeacherRetrieveUpdateSer

三、通过示例代码逐步展示封装流程

逻辑代码展示:(可通过查看继承类的源码加深理解)

#views.py
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from app.models import StudentModel
from app.ser_student import StudentSerializer
# 混入类
from rest_framework.mixins import ListModelMixin,CreateModelMixin
from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
# 扩展类
from rest_framework.generics import ListAPIView,CreateAPIView
from rest_framework.generics import RetrieveAPIView,UpdateAPIView,DestroyAPIView
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
# 视图集
from rest_framework.viewsets import ModelViewSet
# GenericAPIView
# 混入类
# 扩展类
#混入类和扩展类的使用
# 1.测试 GenericAPIView
# class IndexGenViews(GenericAPIView):
#     queryset = StudentModel.objects.all() #查询结果集
#     serializer_class = StudentSerializer #序列化器
#
#     lookup_field = 'pk' #指定数据库中字段
#     lookup_url_kwarg = 'id' #
#
#     def get(self, request):
#         stus = self.get_queryset()
#         ser = self.get_serializer(instance=stus, many=True)
#         return Response({"message":"success","data":ser.data})
# -------------------------------------------
# 2.测试 GenericAPIView 配合混入类使用
# class IndexGenViews(GenericAPIView, ListModelMixin,CreateModelMixin):
#     queryset = StudentModel.objects.all()
#     serializer_class = StudentSerializer
#
#     def get(self, request):
#         return self.list(request)
#     def post(self, request):
#         return self.create(request)
# class IndexGenIDViews(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
#     queryset = StudentModel.objects.all()
#     serializer_class = StudentSerializer
#     lookup_field = 'pk'
#     lookup_url_kwarg = 'id'
#
#     def get(self, request, id):
#         return self.retrieve(request)
#     def put(self, request, id):
#         return self.update(request)
#     def delete(self, request, id):
#         return self.destroy(request)
# ------------------------------------------------------------
# 3. 测试 扩展类
# class IndexGenViews(ListAPIView,CreateAPIView):
#     queryset = StudentModel.objects.all()
#     serializer_class = StudentSerializer
# class IndexGenIDViews(RetrieveAPIView,UpdateAPIView,DestroyAPIView):
#     queryset = StudentModel.objects.all()
#     serializer_class = StudentSerializer
#     lookup_field = 'pk'
#     lookup_url_kwarg = 'id'
# 4. 测试 再次封装的扩展类
class IndexGenViews(ListCreateAPIView):
    queryset = StudentModel.objects.all()
    serializer_class = StudentSerializer
class IndexGenIDViews(RetrieveUpdateDestroyAPIView):
    queryset = StudentModel.objects.all()
    serializer_class = StudentSerializer
    lookup_field = 'pk'
    lookup_url_kwarg = 'id'
# 5. 测试,再次封装,ModelViewSet(视图集详解在下篇文章)
class IndexModelSetViews(ModelViewSet):
    queryset = StudentModel.objects.all()
    serializer_class = StudentSerializer
    lookup_field = 'pk'
    lookup_url_kwarg = 'id'
相关文章
|
3天前
|
存储 数据安全/隐私保护 网络架构
DRF Django REST framework 之 认证组件(五)
DRF Django REST framework 之 认证组件(五)
|
2天前
|
存储 前端开发 JavaScript
探索Django:打造高效、可扩展的Web应用(中)
探索Django:打造高效、可扩展的Web应用(中)
6 1
|
4天前
|
安全 API 数据安全/隐私保护
Django REST framework安全实践:轻松实现认证、权限与限流功能
Django REST framework安全实践:轻松实现认证、权限与限流功能
|
4天前
|
JSON 搜索推荐 数据库
Django REST framework数据展示技巧:分页、过滤与搜索的实用配置与实践
Django REST framework数据展示技巧:分页、过滤与搜索的实用配置与实践
|
4天前
|
JSON API 网络架构
Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器
Django REST framework视图集与路由详解:深入理解ViewSet、ModelViewSet与路由映射器
|
2天前
|
SQL 关系型数据库 数据库
探索Django:打造高效、可扩展的Web应用(上)
探索Django:打造高效、可扩展的Web应用(上)
5 0
|
4天前
|
存储 JSON 数据库
Django REST framework关联序列化器详解:掌握复杂关系的序列化与反序列化艺术
Django REST framework关联序列化器详解:掌握复杂关系的序列化与反序列化艺术
|
4天前
|
JSON API 数据格式
Django REST framework序列化器详解:普通序列化器与模型序列化器的选择与运用
Django REST framework序列化器详解:普通序列化器与模型序列化器的选择与运用
|
16天前
|
JSON 前端开发 API
Django进阶:DRF(Django REST framework)
Django进阶:DRF(Django REST framework)
|
2月前
|
JSON API 网络架构
Python Web 开发: 解释 Django REST framework 的作用,以及如何定义序列化器(Serializer)?
Python Web 开发: 解释 Django REST framework 的作用,以及如何定义序列化器(Serializer)?