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

2023-09-21 11:43:14

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 接口开发步骤

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

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

更多推荐

算法刷题 week4

目录1.斐波那契数列题目题解(递推+滚动变量)O(n)剑指offer10-II青蛙跳台阶问题题目题解10.旋转数组的最小数字题目题解(二分)O(n)1.斐波那契数列题目题解(递推+滚动变量)O(n)这题的数据范围很小,我们直接模拟即可。当数据范围很大时,就需要采用其他方式了,可以参考求解斐波那契数列的若干方法。F(0)

详解WebSocket

目录1.WebSocket是什么?2.WebSocket的通信过程3.WebSocket的报文结构4.JAVA中的WebSocket1.WebSocket是什么?在传统的BS体系中,请求响应一直是单向的,服务器一直扮演的”被动“的角色,浏览器发起请求去访问服务器,服务器才会返回响应。这种单向的模式让实时通信、消息推送一

Vue3项目中使用插槽

前言:此文章仅记录插槽的使用,用于自己后期学习查看。代码实现过程中,HelloWorld为子组件,HomeView为父组件<slot></slot>元素:是一个插槽出口,是写在子组件中的,表示了父组件提供的插槽内容将在子组件哪一个位置展示。默认插槽:HellowVorld组件内容:情况一:HomeView组件不提供插槽

百川的大模型KnowHow

卷友们好,我是rumor。大模型是一个实验工程,涉及数据清洗、底层框架、算法策略等多个工序,每个环节都有很多坑,因此知道如何避坑和技术选型非常重要,可以节省很多算力和时间,说白了就是一摞摞毛爷爷。近期百川智能发布了Baichuan2的7B和13B版本,可能不少卷友被刷屏惯了没有仔细看,他们在放出模型的同时也给了一份技术

vue.js路由如何配置,及全局前置路由守卫(做所有请求登录验证)、路由独享守卫(访问路由前身份验证)

1.编写路由配置文件router.js以及配置全局前置路由守卫和路由独享守卫//路由配置文件//作用是将指定的路由地址切换成对应的模块//eslint-disable-next-lineno-unused-varsimportRouterfrom"vue-router"//eslint-disable-next-lin

HelpLook全新升级!定制AI问答机器人,企业内容中心焕新

一直以来,企业都在努力解决内外部“企业知识管理”问题:从纸质手册发放,转线上电子文档传阅(pdf/ppt/word等),再到整理客户常见问题(FAQ)和内部知识库(wiki),但始终没有找到一套完整方案将“企业知识”很好地集中管理及分享查阅。持续困扰大家的⬇️❌要么是软件系统更新太困难、或搭建费用太昂贵❌要么是没人知道

MybatisX快速生成代码(mybatis plus模板)

文章目录1、概述2、基本使用2.1、插件安装2.2、集成数据库1、概述MybatisX是一款基于IDEA的快速开发插件,为效率而生。在开发过程中,相信大家都遇到过一个数据库内有着十几张或比之更多的数据表的情况。而面对这众多的数据表,实体类、服务类、服务实现类、Mapper接口及其对应的XML文件更是头大,这无疑是成倍增

IPV6真的神

ipv6地址短缺的现实,万物互联的未来<全局可达性>1、路由表更小。地址分配遵循聚类原则,路由表用Entry的路由表示一片子网。2、更强的组播以及流控制。为媒体服务质量QoS。控制提供了良好的网络平台。3、DHCPv6,自动配置地址。使得网(尤其是局域网)的管理更加方便和快捷。4、自带IPSec,端对端安全。在网络层的

通讯网关软件001——利用CommGate X2Access-U实现OPC UA数据转储Access

本文介绍利用CommGateX2ACCESS-U实现从OPCUAServer读取数据并同步转储至ACCESS数据库。CommGateX2ACCESS-U是宁波科安网信开发的网关软件,软件可以登录到网信智汇(http://wangxinzhihui.com)下载。【案例】如下图所示,实现从OPCUAServer实时读取数

linux vim操作汇总

汇总起来,备忘查看~目录1、复制复制一行包括换行符复制光标开始到行末的文本复制光标开始到行首的文本复制当前单词复制单行或多行到指定行后2、粘贴、剪贴3、移动4、删除删除整行删除光标所在行删除光标所在行开始的3行删除一行带复制(当前光标所在行)删除当前行开始的几行(包括当前行)删除到本行行首/行尾删除字符删除单词/符号5

探索Go语言在机器学习领域的应用局限与前景

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

热文推荐