【Django】 rest_framework接口开发流程及接口功能组成

rest_framework接口开发流程及接口功能组成


使用restframework框架开发接口,方式应该有6、7种,每个人的习惯不同,用的方法也不一样,再次不再一一详述。
我比较常用:ModelSerializer+GenericAPIView
原因是用视图函数+装饰器、视图类+继承APIView、或者混入Mixin这三种封装层次有点低,用一个封装层次低的接口,通常意味着你需要写更多的代码,后期也需投入更多的精力去维护它,当然,好处是写出来的代码比较容易看懂;而使用ViewSets(视图集)则刚好相反,ViewSets封装了GenericAPIView,它显得有些画蛇添足,过高的封装层次可能会让你感到云里雾里,当然,好处是用熟了之后会很爽。
所以,在能理解和接受的程度与接口封装的层次两方面来权衡,我选择了GenericAPIView来写视图,ModelSerializer当然也比单纯的Serializer更好用,写更少的代码,做更多的事。


1 Django rest_framework开发的一个符合RESTful标准的接口组成及功能

Django框架它整个采用的是MVT的架构,这三部分各司其职,由M负责与数据库的实际交互;V负责业务逻辑;T负责接受请求与展示响应(实际就是前端)。那我们可以这么理解,只要有一个东西它具备了接受请求(入参)与展示响应(返回值)的功能,我们就可以把它当成T,因为它具备了T的功能。前后端不分离的时候,一切都是那么的美好。
当前后端分离的时候,我们突然发现,T不见了。那么谁来充当T的角色呢,没错是Serializer(负责接受请求与展示响应)。这样一来,前后端分离与不分离,就有了一个统一的架构,也即一个接口通常由三大主要的部分组成:模型、视图、序列化器

1.1 模型M(models.py)

在Django框架的MVT架构中,M承担了与数据库进行交互的功能,但是由于我们用的是ORM,所以只需要将python对象映射到数据模型即可,也就是定义python对象,并在该对象中声明相应的字段。需要注意的一点是,在定义python对象之前,需要先绘制ER图,明确实体间的关系,确保每一个实体,都至少遵循第三范式(3NF)。

说明:前后端分离与不分离,models并没有什么区别

1.2 序列化器T(Serializers.py)

前后端不分离的时候,T其实就是前端,接受请求并返回响应数据。
前后端分离的时候,序列化器承担了这个功能,接受前端请求返回响应数据
如果使用ModelSerializer来定义序列化器,那么它大概长这个样子:

"""
序列化器
"""

from rest_framework import serializers
from .models import *
import re


class MyModelSerializer(serializers.ModelSerializer):
    """
    MyModel 序列化器
    """

    class Meta:
    	"""
		model 模型
		fields 接口入参
		extra_kwargs 入参的约束
		"""
        
        model = MyModel
        fields = ('name', 'mobile')
        
        extra_kwargs = {
    
    
            'mobile': {
    
    
                'write_only': True,
                'min_length': 8,
                'max_length': 16,
            }
        }

    def validate_name(self, name):
        """
        对name的校验
        """

        if User.objects.filter(username=username).count():
            raise serializers.ValidationError("该用户名已被注册")
        
        return name
    
    def validate_mobile(self, mobile):
        """
        判断手机号格式
        判断手机号是否已注册
        """

        # 注册
        if User.objects.filter(mobile=mobile).count():
            raise serializers.ValidationError("该手机号已被注册")
        
        # 判断手机号码格式是否有误
        REGEX_MOBILE = '1[358]\d{9}$|^147\d{8}$|^176\d{8}$'

        # 格式
        if not re.match(REGEX_MOBILE, mobile):
            raise serializers.ValidationError("手机号格式有误")
        
        return mobile
    
    
    def create(self, validated_data):
        """
        validated_data 通过校验的数据 是一个字典
        Serializer中重写create可以对数据做一些修改
        最终将返回一个实例 该实例会给到对应的视图View
        """
        
        user = super().create(validated_data)
        
        # Your code

        return user

在序列化器Serializer中,容易让人感到困惑的可能就是前端字段校验这一块。其实,我们回到Serializers的功能接受前端请求返回响应数据,就能明白为什么它要序列化与反序列化。

  • 序列化:python对象转变为可传输(可被用于前端渲染)的JSON格式(也可能是xml等)字符串,究其原因是因为我们用的ORM,第一步ORM读数据,拿出来的是一个查询集(set对象),需要把它变成前端喜欢的样子。
  • 反序列化字符串变为python对象。从前端得到的入参,必然是字符串格式,想要把它存到数据库里,还得靠ORM,但是ORM喜欢的是python对象,所以需要一个反序列化的过程。

在反序列化的过程中,我们不希望用户输入一些非法的参数,所以要在Serializer中定义入参的约束与自定义的校验方式,校验通过则返回一个模型的实例给视图,否则返回错误信息。
这就是Serializer的功能与Model及View之间的关系。

1.3 视图V(views.py)

模型和序列化器固然重要,但是视图才是核心,因为通常情况下,业务逻辑都集中在views中,由视图完成。

在视图中你可以通过重写get/create方法,完成业务逻辑。
如果你像我一样使用的是GenericAPIView来写视图函数,那么你的View应该长这个样子:


class MyModelCreateView(generics.CreateAPIView):
    """
    创建视图
    """

    # permission_classes = [permissions.IsAuthenticated]
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer


    def post(self, request, *args, **kwargs):
    	"""
		重写post 四核可以不用重写
		"""
        serializer_data = MyModelSerializer(data=request.data)
        
        if serializer_data.is_valid():
            return super().post(request, *args, **kwargs)
        
        else:
            return Response(serializer_data.errors)

    
    def create(self, request, *args, **kwargs):
    	"""
		重写create 写自己的业务逻辑
		如果继承的是ListAPIView 就重写create
		"""
        # 获取前端传入的数据
        field= request.POST.get("xx")
        
        # Your code
        
        return JsonResponse(
            data={
    
    
                'data': data,
                'msg': 'OK',
                'code': 1,
            },
            safe=False
        )

重写create/get方法时,通过reques获取从前端传过来的入参,拿到入参之后,你就可以写自己的业务逻辑了。


2 Django DRF 接口开发步骤

  • 模型设计,需要注意关系规范化
  • 序列化器,需要知道哪些是入参,分别需要怎样的约束
  • 视图,写业务逻辑、权限配置、过滤查询分页等

我通常是先写模型,然后是序列化器,最后再写业务逻辑以及接口的其他功能,每个人的方法可能不同,也就不详述了。

猜你喜欢

转载自blog.csdn.net/qq_42774234/article/details/133090421