DRF 框架总结

DRF 框架总结

安装配置

安装

pip install djangorestframework==3.12.4
版本要求:djangorestframework==3.12.4
        Python (3.5, 3.6, 3.7, 3.8, 3.9)
        Django (2.2, 3.0, 3.1)
    
版本要求:djangorestframework==3.11.2
        Python (3.5, 3.6, 3.7, 3.8)
        Django (1.11, 2.0, 2.1, 2.2, 3.0)

配置

在 settings.py 中配置 rest_framework

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]

request 的变化

变化

  • Django 原生的 requetdjango.core.handlers.wsgi.WSGIRequest 类的对象
# Django CBV
from django.views import View

class UserView(View):
        def get(self,request):
            request.method
            request.POST
            request.GET
            request.body
  • drf 框架,视图中的 request 对象,是对 djangorequest 进行了一次封装,完善了一些功能,增加了认证权限解析器等功能
from rest_framework.views import APIView
from rest_framework.response import Response

class UserView(APIView):
    def get(self, request, *args, **kwargs):
        # request,不再是django中的request,而是又被封装了一层,
        # 内部包含:django的 request、认证、解析器等。
        return Response({"code": 1000, "data": "xxx"})

    def post(self, request, *args, **kwargs):
        return Response({"code": 1000, "data": "xxx"})
# rest_framework.request.Request 类

class Request:

    def __init__(self, request, parsers=None, 
                 authenticators=None,negotiator=None, parser_context=None):
        self._request = request
        self.parsers = parsers or ()
        self.authenticators = authenticators or ()
        
    @property
    def query_params(self):
        return self._request.GET

    @property
    def data(self):
        if not _hasattr(self, '_full_data'):
            self._load_data_and_files()
        return self._full_data
    
    def __getattr__(self, attr):
        try:
            return getattr(self._request, attr) # self._request.method
        except AttributeError:
            return self.__getattribute__(attr)

源码流程

img

举例1

# django 和 drf 的 request.POST 都能解析 url-form-encoded 类型的数据
# django一旦读取到 v1=123&v2=456&v3=999 请求头之后,
# 就会按照 {"v1":123,"v2":456,"v3":999} 解析

# postman 测试;发送 post请求;
# 查看 django的drf的request对象,获取post请求数据的区别
# 向下面两个视图发送的请求
# 举例:

url: http://127.0.0.1:8000/index/
method: POST
content-type: application/json
data: {
          "data": "test"
      }
# 结论:
# django request 对象无法解析 application/json 类型的数据
# django视图中的 request 对象
class IndexView(View):
    def post(self, request):
        # print(request.data) # django request 中不存在 request.data 属性
        print(json.loads(request.body))  # 获取 post请求方法中的 json 数据
        print(request.POST)              # <QueryDict: {}>
        response = {
            'code': 1,
            'msg': 'this is post method'
        }
        return JsonResponse(response)
# drf 中视图的 request 对象
class IndexView(APIView):

    def post(self, request):
        print(request.data, type(request.data)) # {"data": "test"} dict
        print(request.POST)                     # <QueryDict: {}>
        response = {
            'code': 1,
            'msg': 'this is post method'
        }
        return Response(response)

举例2

from rest_framework.views import APIView
from rest_framework.response import Response
from django.views import View
from rest_framework.request import Request


class UserView(APIView):
    def get(self, request, *args, **kwargs):
        
        # 通过对象的嵌套直接找到原 django中的 request对象,读取相关值
        request._request.method
        request._request.GET
        request._request.POST
        request._request.body

        # 直接读取新request对象中的值,一般此处会对原始的数据进行一些处理,方便开发者在视图中使用。
        request.query_params  # 内部本质上就是 request._request.GET
        # 内部读取请求体中的数据,并进行处理,
        # 例如:请求者发来JSON格式,他的内部会对json字符串进行反序列化。
        request.data 
        # 通过 __getattr__ 去访问 request._request 中的值
        request.method

版本控制

URL的GET参数传递

方式

url: http://127.0.0.1:8000/index?verson=v1/

配置

# setting.py
REST_FRAMEWORK = {
    "VERSION_PARAM": "version",      # 版本参数 ?version=v1
#   "VERSION_PARAM": "v",            # 版本参数 ?v=v2
    "DEFAULT_VERSION": "v1",         # 默认版本号 
    "ALLOWED_VERSIONS": ["v1", "v2", "v3"],
    "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.QueryParameterVersioning"
}

获取

class VersionGet(APIView):
    # 版本类 可以写在配置文件中
    # versioning_class = QueryParameterVersioning
    def get(request):
        print(request.version)  # 获取版本号
        response = {
            'code': 1,
            'msg': 'This is get method'
        }
        return Response(response)

URL路径传递

方式

url: http://127.0.0.1:8000/api/v1/

配置

# setting.py
REST_FRAMEWORK = {
    "DEFAULT_VERSION": "v1",         # 默认版本号 
    "ALLOWED_VERSIONS": ["v1", "v2", "v3"],
    "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning"
}

获取

urlpatterns = [
    path('api/<str:version>/', views.IndexView.as_view()),
]
class IndexView(APIView):
    # versioning_class = QueryParameterVersioning

    def get(self, request, *args, **kwargs):
        print(request.version)  # v1
        response = {
            'code': 1,
            'msg': 'this is get method'
        }
        return Response(response)

源码分析

img

认证

源码

img

权限

源码

img

序列化

drf 中为我们提供了 Serializer 主要又两大功能:

  1. 对请求数据的校验 进入数据库
  2. 对数据库查询到的对象进行序列化

数据校验

示例准备

数据表

class Role(models.Model):
    """ 角色表 """
    title = models.CharField(verbose_name="名称", max_length=32)


class Department(models.Model):
    """ 部门表 """
    title = models.CharField(verbose_name="名称", max_length=32)


class UserInfo(models.Model):
    """ 用户表 """
    level_choices = ((1, "普通会员"), (2, "VIP"), (3, "SVIP"),)
    level = models.IntegerField(verbose_name="级别", choices=level_choices, default=1)

    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=64)
    age = models.IntegerField(verbose_name="年龄", default=0)
    email = models.CharField(verbose_name="邮箱", max_length=64)
    token = models.CharField(verbose_name="TOKEN", max_length=64, null=True, blank=True)

    # 外键
    depart = models.ForeignKey(verbose_name="部门", to="Department", on_delete=models.CASCADE)

    # 多对多
    roles = models.ManyToManyField(verbose_name="角色", to="Role")

示例1

# post 提交数据
{
    "username":"kukudehan",
    "age": 18,
    "level": "1", 
    "email":"1231@qq.com",
    "email2":"12450@qq.com",
    "email3":"12450@qq.com",
    "roles": [1, 2]
}
# 数据校验示例一
class UserSerializer(serializers.Serializer):
    username = serializers.CharField(label="姓名", min_length=6, max_length=32)
    age = serializers.IntegerField(label="年龄", min_value=0, max_value=200)
    # choices = level_choices = ((1, "普通会员"), (2, "VIP"), (3, "SVIP"),)
    level = serializers.ChoiceField(label="级别", choices=models.UserInfo.level_choices)
    # 第一种验证规则 用django 内置的验证
    email = serializers.CharField(label="邮箱", validators=[EmailValidator, ])
    # 不进行校验
    email1 = serializers.CharField(label="邮箱1", )
    # 第二种验证规则 自己编写验证的类
    email2 = serializers.CharField(label="邮箱2", validators=[RegexValidator(r"^\w+@\w+\.\w+$")])
    # 第三种验证规则 用钩子函数进行验证
    email3 = serializers.CharField(label="邮箱3", )

    # 局部钩子函数 只校验 email3 的数据是否符合规范
    def validate_email3(self, value):
        """
        钩子函数 用与验证某个字段
        """
        if re.match(r"^\w+@\w+\.\w+$", value):
            return value
        raise exceptions.ValidationError("邮箱格式错误")
        
# 数据校验视图类
class UserModelView(APIView):

    def post(self, request):
        # request.data 既可以解析表单格式的数据 又可以解析 json 数据 很牛
        data = request.data
        ser = UserSerializer(data=data, )
        # 校验数据是否正确
        if not ser.is_valid():
            # 获取错误字段信息
            errors = ser.errors
            return Response({'code': 1001, 'data': errors})
        # 这是一个继承字典类的数据结构
        data = ser.validated_data
        return Response({'code': 200, 'data': data})    

示例2

# post 提交数据
{
    "username":"kukudehan",
    "age": 18,
    "email":"1231@qq.com"
}
# 数据校验示例二
class UserModelSerializer(serializers.ModelSerializer):

    class Meta:
        # 想要校验的数据表
        model = models.UserInfo
        # 想要序列化的字段
        fields = ["username", "age", "email", ]
        # 部分字段的额外要求
        extra_kwargs = {
            'username': {"min_length": 6, "max_length": 32},
            'email': {"validators": [EmailValidator, ]}
        }

# 数据校验视图类        
class UserModelView(APIView):

    def post(self, request):
        # request.data 既可以解析表单格式的数据 又可以解析 json 数据 很牛
        data = request.data
        ser = UserModelSerializer(data=data,)
        if not ser.is_valid():
            errors = ser.errors
            return Response({'code': 1001, 'data': errors})
        # 这是一个类似字典的数据结构
        data = ser.validated_data
        return Response({'code': 200, 'data': data})        

示例3

# post 提交数据
{
    "username":"kukudehan",
    "age": 18,
    "email":"1231@qq.com",
    "email2":"12450@qq.com",
    "email3":"12450@qq.com",
    "roles": [1, 2]
}
from rest_framework import serializers
from django.core.validators import EmailValidator

# 自己编写的验证类
class RegexValidator(object):
    def __init__(self, base):
        self.base = str(base)

    # RegexValidator(base=base)(value=value) 时执行
    def __call__(self, value):
        match_object = re.match(self.base, value)
        if not match_object:
            raise serializers.ValidationError("格式错误")

# 数据校验示例三
class UserModelSerializer(serializers.ModelSerializer):
    email2 = serializers.CharField(label="邮箱2", 
                                   validators=[RegexValidator(r"^\w+@\w+\.\w+$")])
    email3 = serializers.CharField(label="邮箱3")

    # depart roles 这种一对多 多对多的字段 一定要用 json 发送
    class Meta:
        model = models.UserInfo
        # 想要序列化的字段
        fields = ["username", "age", "email", "email2", "email3", "depart", "roles"]
        # 部分字段的额外要求
        extra_kwargs = {
            'username': {"min_length": 6, "max_length": 32},
            'email': {"validators": [EmailValidator, ]}
        }

    # 局部钩子函数 只校验 email3 的数据是否符合规范
    def validate_email3(self, value):
        """
        钩子函数 用与验证某个字段
        """
        if re.match(r"^\w+@\w+\.\w+$", value):
            return value
        raise exceptions.ValidationError("邮箱格式错误")
        
class UserModelView(APIView):

    def post(self, request):
        # request.data 既可以解析表单格式的数据 又可以解析 json 数据 很牛
        data = request.data
        ser = UserModelSerializer(data=data,)
        if not ser.is_valid():
            errors = ser.errors
            return Response({'code': 1001, 'data': errors})
        ser.validated_data.pop("email2")
        ser.validated_data.pop("email3")
        ser.save(level=1, password="1234")
        # 这是一个类似字典的数据结构
        data = ser.validated_data
        return Response({'code': 200, 'data': data})        

序列化

示例1 (多表序列化)

# 序列化示例一
class UserSerializers(serializers.ModelSerializer):
    # 显示选择的 level
    level_text = serializers.CharField(source="get_level_display")
    # 显示 depart 部门一对多 内部反射机制 depart.title
    # source 参数可以给字段取别名
    depart = serializers.CharField(source="depart.title")
    # 角色多对多字段
    roles = serializers.SerializerMethodField()
    # 额外的字段
    extra = serializers.SerializerMethodField()

    class Meta:
        model = models.UserInfo
        # 想要序列化的字段
        fields = ["username", "age", "email", 
                  "level_text", "depart", "roles", "extra"]
        # 部分字段的额外要求
        extra_kwargs = {
            'username': {"min_length": 6, "max_length": 32},
            'email': {"validators": [EmailValidator, ]}
        }

    # SerializerMethodField() 类的钩子函数 处理 roles 字段 
    # 注意一定要 roles = SerializerMethodField() 这个类才可以写下面的钩子函数
    def get_roles(self, obj):
        data_list = obj.roles.all()
        return [model_to_dict(item, ["title"]) for item in data_list]
        # return [model_to_dict(item, ["id", "title"]) for item in data_list]

    # 钩子函数 处理自己额外添加的 extra 字段
    def get_extra(self, obj):
        return 666

class UserView(APIView):
    """ 用户管理 """
    def get(self, request):
        queryset = models.UserInfo.objects.all()
        ser = UserModelSerializer(instance=queryset, many=True)
        return Response({'code': 0, 'data': ser.data})
  • SerializerMethodField: 这是一个只读字段。它通过调用附加到的序列化程序类上的方法来获取其值。它可用于将任何类型的数据添加到对象的序列化表示中。

示例2 (多表序列化)

# 序列化示例二
class DepartModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Department
        fields = "__all__"

class RoleModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = "__all__"

class UserSerializers(serializers.ModelSerializer):
    # 显示选择的 level
    level_text = serializers.CharField(source="get_level_display")
    # 显示 depart 部门 一对多
    depart = DepartModelSerializer()
    # 角色多对多字段
    roles = RoleModelSerializer(many=True)

    class Meta:
        model = models.UserInfo
        # 想要序列化的字段
        fields = ["username", "age", "email", "level_text", "depart", "roles"]
        
# 序列化视图类        
class UserModelViews(APIView):

    def get(self, request):
        queryset = models.UserInfo.objects.all()
        ser = UserSerializers(instance=queryset, many=True)
        return Response({'code': 0, 'data': ser.data})        

数据校验&序列化

"""
    数据校验 和 序列化
    注意:数据校验是将请求发送过来的数据进行校验,一般情况下校验无问题 入库
    序列化是将数据库中的数据,以 json 格式进行 response
"""

from django.core.validators import EmailValidator
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from . import models

# 多表序列化
class DepartModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Department
        # 要显示的字段
        fields = ['id', 'title']
        # 加上 extra_kwargs 字段后
        extra_kwargs = {
            "id": {"read_only": False},
            "title": {"read_only": True}
        }

class RoleModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = ["id", "title"]
        extra_kwargs = {
            "id": {"read_only": False},
            "title": {"read_only": True}
        }

class UserModelSerializer(serializers.ModelSerializer):
    level_text = serializers.CharField(
        source="get_level_display",
        read_only=True
    )
    depart = DepartModelSerializer(many=False)  # 如果不写 read_only = True 必须重写 create 方法
    roles = RoleModelSerializer(many=True)
    extra = serializers.SerializerMethodField(read_only=True)
    email2 = serializers.EmailField(write_only=True)

    class Meta:
        model = models.UserInfo
        fields = [
            "username", "age", "email", "level_text",
            "depart", "roles", "extra", "email2"
        ]
        extra_kwargs = {
            "age": {"read_only": True},
            "email": {"validators": [EmailValidator, ]}
        }

    def get_extra(self, obj):
        return 666

    def validate_username(self, value):
        return value

    def create(self, validated_data):
        # 由于 post 发送的是 {"depart": {"id": 1}} 所以需要将 depart 更改为 depart_id
        depart_id = validated_data.pop("depart")['id']
        # 由于 post 发送的是 {"roles": {"id": 1}, {"id": 2}} 所以需要将 depart 更改为 depart_id
        role_id_list = [ele['id'] for ele in validated_data.pop('roles')]
        # 更换
        validated_data['depart_id'] = depart_id
        user_object = models.UserInfo.objects.create(**validated_data)
        # 多对多添加数据 类似如下:
        # user_id role_id
        #    1       2
        #    1       3
        user_object.roles.add(*role_id_list)
        return user_object
# 视图类
class UserView(APIView):

    def get(self, request):
        queryset = models.UserInfo.objects.all()
        ser = UserModelSerializer(instance=queryset, many=True)
        return Response({"code": 0, "data": ser.data})

    def post(self, request):
        ser = UserModelSerializer(data=request.data)
        if not ser.is_valid():
            return Response({"code": 1001, "data": ser.errors})
        ser.validated_data.pop("email2")
        # save 中调用 create 方法
        instance = ser.save(age=19, password="123")
        return Response({'code': 0, 'data': "创建成功"})

反序列化


源码解析

img

img

img

视图类

  1. APIView

新增了 免除csrf 请求封装、版本、认证、权限、限流的功能 最基础的 drf 视图类

  1. GenericAPIView

GenericAPIView 继承 APIView,在 APIView 的基础上又增加了一些功能。

例如 get_queryset get_object

实际在开发中一般不会直接继承它,他更多的是担任 中间人的角色,为子类提供公共功能。
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

class UserView(GenericAPIView):
    queryset = models.UserInfo.objects.filter(id=1)
    serializer_class = 序列化类
    
    def get(self, request):
        queryset = self.get_queryset()
        ser = self.get_serializer(intance=queryset,many=True)
        return Response({"code": 0, 'data': "..."})    
  1. ViewSetMixin

ViewSetMixin将 get/post/put/delete 等方法映射到 listcreateretrieveupdatepartial_updatedestroy方法中,让视图不再需要两个类。

# urls.py

from django.urls import path, re_path, include
from app01 import views

urlpatterns = [
    path('api/users/', views.UserView.as_view({"get":"list","post":"create"})),
    path('api/users/<int:pk>/', views.UserView.as_view({"get":"retrieve","put":"update","patch":"partial_update","delete":"destory"})),
]
# views.py

from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response

class UserView(GenericViewSet):
    
    # 认证、权限、限流等
    queryset = models.UserInfo.objects.filter(status=True)
    serializer_class = 序列化类
    
    def list(self, request):
        # 业务逻辑:查看列表
        queryset = self.get_queryset()
        ser = self.get_serializer(intance=queryset, many=True)
        return Response({"code": 0, 'data': "..."})

    def create(self, request):
        # 业务逻辑:新建
        return Response({'code': 0, 'data': "..."})
    
    def retrieve(self, request, pk):
        # 业务逻辑:查看某个数据的详细
        return Response({"code": 0, 'data': "..."})

    def update(self, request, pk):
        # 业务逻辑:全部修改
        return Response({'code': 0, 'data': "..."})
    
    def partial_update(self, request, pk):
        # 业务逻辑:局部修改
        return Response({'code': 0, 'data': "..."})
    
    def destory(self, request, pk):
        # 业务逻辑:删除
        return Response({'code': 0, 'data': "..."})
  1. GenericViewSet

GenericViewSet类中没有定义任何代码,他就是继承 ViewSetMixinGenericAPIView,也就说他的功能就是将继承的两个类的功能继承到一起。

源码:

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
  1. 五大视图类

drf 中为我们提供了 5 个 用于做增、删、改(局部修改)、查列表、 查单个数据的 5 个类(需要结合GenericViewSet 使用)

ListModelMixin, CreateModelMixin,

RetrieveModelMixin`, `UpdateModelMixin`,`DestroyModelMixin

示例1

# urls.py

from django.urls import path, re_path, include
from app01 import views

urlpatterns = [
    path('api/users/', views.UserView.as_view({"get":"list","post":"create"})),
    path('api/users/<int:pk>/', views.UserView.as_view({"get":"retrieve","put":"update","patch":"partial_update","delete":"destroy"})),
]
# views.py

from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import (
    ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin,
    DestroyModelMixin
)

class UserView(CreateModelMixin, ListModelMixin,
    RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):
    
    queryset = models.UserInfo.objects.filter(status=True)
    serializer_class = 序列化类

示例2

# urls.py

from django.urls import path
from app01 import views

urlpatterns = [
    path('api/users/', views.UserView.as_view({"get": "list", "post": "create"})),
    path('api/users/<int:pk>/', views.UserView.as_view({"get": "retrieve"})),
]
# views.py

from rest_framework import serializers
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from app01 import models


class UserModelSerializer(serializers.ModelSerializer):
    level_text = serializers.CharField(
        source="get_level_display",
        read_only=True
    )
    extra = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = models.UserInfo
        fields = ["username", "age", "email", "level_text", "extra"]

    def get_extra(self, obj):
        return 666


class UserView(mixins.ListModelMixin, mixins.RetrieveModelMixin, 
               mixins.CreateModelMixin, GenericViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = UserModelSerializer

    def perform_create(self, serializer):
        """ 序列化:对请求的数据校验成功后,执行保存。"""
        serializer.save(depart_id=1, password="123")

示例3

# urls.py

from django.urls import path
from app01 import views

urlpatterns = [
    path('api/users/', views.UserView.as_view(
        {"get": "list", "post": "create"}
    )),
    path('api/users/<int:pk>/', views.UserView.as_view(
        {"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"}
    )),
]
# views.py

from rest_framework import serializers
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from app01 import models


class UserModelSerializer(serializers.ModelSerializer):
    level_text = serializers.CharField(
        source="get_level_display",
        read_only=True
    )
    extra = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = models.UserInfo
        fields = ["username", "age", "email", "level_text", "extra"]

    def get_extra(self, obj):
        return 666


class UserView(mixins.ListModelMixin,
               mixins.RetrieveModelMixin,
               mixins.CreateModelMixin,
               mixins.UpdateModelMixin,
               mixins.DestroyModelMixin,
               GenericViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = UserModelSerializer

    def perform_create(self, serializer):
        """ 序列化:对请求的数据校验成功后,执行保存。"""
        serializer.save(depart_id=1, password="123")
        
    def perform_update(self, serializer):
        serializer.save()
        
    def perform_destroy(self, instance):
        instance.delete()
  1. ModelViewSet

ModelViewSet 继承了 五大视图类GenericViewSet

# urls.py

from django.urls import path
from app01 import views

urlpatterns = [
    path('api/users/', views.UserView.as_view(
        {"get": "list", "post": "create"}
    )),
    path('api/users/<int:pk>/', views.UserView.as_view(
        {"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"}
    )),
]
# views.py
from rest_framework import serializers
from rest_framework.viewsets import ModelViewSet
from app01 import models

class UserModelSerializer(serializers.ModelSerializer):
    level_text = serializers.CharField(
        source="get_level_display",
        read_only=True
    )
    extra = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = models.UserInfo
        fields = ["username", "age", "email", "level_text", "extra"]

    def get_extra(self, obj):
        return 666

class UserView(ModelViewSet):
    queryset = models.UserInfo.objects.all()
    serializer_class = UserModelSerializer

    # 钩子函数 可以在create前修改内容
    def perform_create(self, serializer):
        """ 序列化:对请求的数据校验成功后,执行保存。"""
        serializer.save(depart_id=1, password="123")
  1. 视图类继承关系

img

视图类总结

  1. 接口与数据库操作无关, 直接继承APIView
  2. 接口背后需要对数据库进行操作,一般:ModelViewSet CreateModelMixin ListModelMixin
利用钩子自定义功能
重写某个方法 实现更加完善的功能
posted @ 2022-03-01 09:23  隔江千万里  阅读(302)  评论(0)    收藏  举报