Django笔记(六):DRF框架

前后端分离是互联网应用开发的标准使用方式,让前后端通过接口实现解耦,能够更好的进行开发和维护。

RESTful接口常见规范

在接口设计中,大家遵循一定的规范可以减少很多不必要的麻烦,例如url应有一定辨识度,可以加入api等关键词,路径中尽量不要含有动词,根据请求方式对业务逻辑进行划分等等,如:

请求方式数据库操作描述
GETSELECT获取数据
POSTCREATE添加数据
PUTUPDATE更新数据
DELETEDELETE删除数据

DRF安装

安装命令:

pip install djangorestframework

settings.py注册:

INSTALLED_APPS = [
    "rest_framework",
    ...
]

视图编写

app/views.py

from rest_framework.views import APIView
from rest_framework.response import Response

class IndexView(APIView):
    def get(self, request):
        res = dict()
        res['mes'] = "success"
        res['data'] = 123
        return Response(res)

视图函数变成了视图类,需要继承APIView。可在类内部分别定义get,post等请求函数,视图会根据请求方式映射不同处理函数。

路由配置

每条路由对应一个视图函数,故需将视图类转为视图函数

urls.py

from django.contrib import admin
from django.urls import path
from app1 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.IndexView.as_view()),
]

访问指定路由后:

 DRF框架自带的接口界面很好看,也便于调试。

序列化操作

将数据库数据整理为接口返回数据的过程很繁琐,DRF简化了序列化操作。

定义model,/app/models.py

from django.db import models

# Create your models here.
class Player(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)

定义了player模型,两个字段id和name。为了方便后台操作,我们将其进行admin注册(app/admin.py)

from django.contrib import admin
from app.models import Player
# Register your models here.

admin.site.register(Player)

记得进行数据迁移!!!之后便可在admin管理界面看到Player表格,登录admin管理系统需要创建用户,创建命令:

python manage.py createsuperuser

按提示注册后,登录admin管理界面:

可以看到创建的表格,手动添加两条数据。如果我们希望返回所有player信息,视图应该这么写(app/views.py):

from rest_framework.views import APIView
from rest_framework.response import Response
from app1.models import Player

class PlayersView(APIView):
    def get(self, request):
        players = Player.objects.all()
        res = list()
        for p in players:
            t = dict()
            t["id"] = p.id
            t["name"] = p.name
            res.append(t)
        return Response(res)

 字段较少的时候无妨,字段太多的时候,这是个让人抓狂的操作。

可以先编写一个序列化类(app/serializer.py):

from rest_framework import serializers
from app1.models import Player

class PlayersModelSerializer(serializers.ModelSerializer):
    class Meta:
        model=Player
        # fields="__all__"
        fields = ("id", "name")

此类用于对Player进行序列化,Meta类中只需指明指定模型,以及想要序列化的字段即可,fields的all参数指所有字段。

视图修改(app/views.py):

from rest_framework.views import APIView
from rest_framework.response import Response
from app1.models import Player
from app1.serializers import PlayersModelSerializer

class PlayersView(APIView):
    def get(self, request):
        players = Player.objects.all()
        # 创建序列化对象,many指多条数据
        players_json = PlayersModelSerializer(players, many=True)
        print(players_json.data)
        # data返回序列化后的数据
        return Response(players_json.data)

设置路由后,访问结果:

ModelSerializer只是对模型进行序列化,如果对其以外复杂结构进行序列化,可以继承Serializer类,逐个字段进行手动编写,以及序列化嵌套等等,不在赘述。

Mixins类改进

Django的mixins实现了各种功能让其他函数继承,能够让用户用更少的代码操作模型,一般会配合GenericAPIView使用,Mixin有五类:

描述请求方法
ListModelMixin返回查询集列表,提供list方法GET
CreateModelMixin创建实例,提供create()方法POST
RetrieveModelMixin返回一个具体实例,提供retrieve()方法GET
UpdateModelMixin更新实例,提供update()方法PUT、PATCH
DestoryModelMixin删除实例,提供delete()方法DELETE

同样实现上面返回player列表的功能,视图可以这样写(app/views.py):

from rest_framework import mixins, generics
from app1.models import Player
from app1.serializers import PlayersModelSerializer

class PlayersView(mixins.ListModelMixin, generics.GenericAPIView):
    queryset = Player.objects.all()
    serializer_class = PlayersModelSerializer
    def get(self, request):
        return self.list(request)

queryset和serializer_class是要操作的数据集合序列化类,GenericAPIView需要的参数。因为ListModelMixin提供了list函数,get请求视图的返回结果可以直接调用。这里的执行结果与上面相同。(如果queryset需要条件查询,需要重写get_queryset函数。

如果是添加数据,则:

from rest_framework import mixins, generics
from app1.models import Player
from app1.serializers import PlayersModelSerializer

class PlayersView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = Player.objects.all()
    serializer_class = PlayersModelSerializer
    def get(self, request):
        return self.list(request)
    def post(self, request):
        return self.create(request)

提供name参数即可添加成功。

另外三个Mixin类使用相同,因为要对指定数据进行修改,故需提供词条数据的pk(主键)来找到此条数据。(app/views.py)

class PlayerDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin,
                       generics.GenericAPIView):
    queryset = Player.objects.all()
    serializer_class = PlayersModelSerializer
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

路由需要提供pk参数:(urls.py)

urlpatterns = [
    path("players/<int:pk>/", views.PlayerDetailView.as_view()),
    ...
]

如果想要通过其他字段查找数据,需要提供lookup_field参数,指明要查找的字段(查询结果多于一条时会报错)

class PlayerDetailView(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin,
                       generics.GenericAPIView):
    queryset = Player.objects.all()
    serializer_class = PlayersModelSerializer
    lookup_field = "name"
    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
urlpatterns = [
    path("players/<name>/", views.PlayerDetailView.as_view()),
    ...
]

 GenericAPIView类

GenericAPIView还有许多子类,直接将Mixins和GenericAPIView进行了组合,有这么多:

提供方法

CreateAPIView

post
ListAPIViewget
RetrieveAPIViewget
DestroyAPIViewdelete
UpdateAPIViewput, patch
ListCreateAPIViewget, post
RetrieveUpdateAPIViewget, put, patch
RetrieveDestroyAPIViewget, delete, patch
RetrieveUpdateDestroyAPIViewget, put, delete, patch

 上面的试图类可以这么写:

class PlayerDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Player.objects.all()
    serializer_class = PlayersModelSerializer
    lookup_field = "name"

言简意赅。

自定义返回数据

DRF提供了自定义返回类,可以自己编写,也可以硬往里赛东西,比如:

def get(self, request, *args, **kwargs):
        res = dict()
        res["mes"] = "success"
        res["data"] = self.list(request, *args, **kwargs).data
        return Response(res)

把原来Response中的data取出来,重新塞点东西再返回。

分页

 DRF有三个分页方式,这里说一个PageNumberPagination,创建一个分页类(app/paginations.py):

from rest_framework.pagination import PageNumberPagination

class PlayerPagination(PageNumberPagination):
    page_size = 2 # 每页显示的数据数量
    max_page_size = 4 # 每页最多显示的数据数量
    page_size_query_param = "size" # 显示数量的变量名
    page_query_param = "page" # 页数的变量名
    """
        如果访问localhost/player/?page=2&size=3,则会返回以三条数据分页的第二页内容
    """

用户视图(app/views.py):

from rest_framework import mixins, generics
from app1.models import Player
from app1.serializers import PlayersModelSerializer
from app1.paginations import PlayerPagination

class PlayersView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = Player.objects.all()
    serializer_class = PlayersModelSerializer
    pagination_class = PlayerPagination
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

 尾

一般APIView配合序列化就能很好开发接口,Mixins和GenericAPIView少不了几行代码,且queryset和response部分限制较多,自定义覆盖原方法的代码也就差不多把少的几行代码补回了,如果需要分页功能,可以用GenericAPIView编写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/344651.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(SSO单点登录)多个系统之间如何实现账号互通

SSO具有以下优点&#xff1a; 降低访问第三方网站风险&#xff1b;降低用户名和密码的管理成本&#xff1b;提高用户试用满意度&#xff1b;SSO使用标准的身份认证和授权协议&#xff0c;如OAuth、OpenID Connect等&#xff0c;可以保障用户身份的安全性和隐私性。 单点登录最大…

Linux 驱动开发基础知识——认识LED驱动程序 (二)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

el-select选择之后值不显示在文本框的问题解决

问题场景如下图&#xff1a; 在el-collapse-item中使用子组件&#xff0c;子组件里是el-form-item代码。el-select在for循环中&#xff0c;可以有多个。 查了一下博客&#xff0c;有的说这种场景需要给el-select添加change事件&#xff0c;加上 this.$forceUpdate() 强制刷新即…

Vue3.0里为什么要用 Proxy API 替代 defineProperty API ?

文章目录 一、Object.defineProperty二、Proxy三、总结参考文献 一、Object.defineProperty 定义&#xff1a;Object.defineProperty() 方法会直接在一个对象上定义一个新属性&#xff0c;或者修改一个对象的现有属性&#xff0c;并返回此对象 为什么能实现响应式 通过define…

Kubeadm安装单master多node节点K8S集群

kubeadm安装k8s1.25版本集群步骤 环境说明实验环境规划集群搭建规划 初始化安装k8s集群的实验环境安装虚拟机更新yum源和操作系统配置机器主机名配置主机hosts文件&#xff0c;相互之间通过主机名互相访问配置主机之间无密码登录关闭交换分区swap&#xff0c;提升性能修改机器内…

[algorithm] 自动驾驶 规划 非线性优化学习系列之1 :车辆横向运动动力学详细解释

写在前面 最近时空联合规划很火&#xff0c;想学习。由于在学校主打学习新能源电力电子方向&#xff0c;转行后也想好好零散的知识体系。计划从车辆运动动力学习&#xff0c;模型预测控制&#xff08;经典控制目前看主打应用&#xff0c;不会再去深入&#xff09;&#xff0c;…

使用js判断list中是否含有某个字符串,存在则删除,

显示上图中使用了两种方式&#xff0c; 左边的是filter将不等于userCode的元素筛选出来组成一个新的list&#xff0c; userCodeList.filter(item> item!userCode)&#xff1b;但是上面这个方法在IE浏览器中不支持&#xff0c; 所以改成了右边的方法&#xff0c;使用splice…

C#,入门教程(22)——函数的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(21)——命名空间&#xff08;namespace&#xff09;与程序结构的基础知识https://blog.csdn.net/beijinghorn/article/details/124140653 一、函数的基本概念 一个软件的结构大体如下&#xff1a; 大厦application: a plaza { --…

01-灵魂一问:智能网联汽车域控SOA如何做?

1. 前言 //TODO 2. SOA&#xff1f;微服务&#xff1f; //TODO 3. 如何设计框架&#xff1f; 3.1 全面SOA SOA平台化&#xff0c;全面解耦操作系统&#xff0c;将操作系统重新分层 3.2 部分SOA 仅仅将部分涉及车辆相关的SOA服务化&#xff0c;比如automotive service …

Java带你快速了解单元测试

一、单元测试 1.1 单元测试快速入门 所谓单元测试&#xff0c;就是针对最小的功能单元&#xff0c;编写测试代码对其进行正确性测试。 我们想想&#xff0c;咱们之前是怎么进行测试的呢&#xff1f; 比如说我们写了一个学生管理系统&#xff0c;有添加学生、修改学生、删除…

MySQL基础(一)

学习数据库的目的&#xff1a; 实现数据持久化到本地。使用完整的管理系统统一管理&#xff0c;可以实现结构化查询&#xff0c;方便管理。 一、数据库概述 数据库&#xff08;DataBase&#xff09; 为了方便数据的存储和管理&#xff0c;它将数据按照特定的 规则存储在磁盘…

成都直播基地应该怎么做?直击西南直播电商行业发展现状

新蓝图已然绘就&#xff0c;新征程击鼓催征。近年&#xff0c;四川电子商务行业的发展势头日益强劲&#xff0c;为助力成都直播产业的多元化发展&#xff0c;由德商产投与无锋科技联袂打造的中国西部大型全域直播产业基地——天府锋巢直播产业基地落户成都市天府新区。该成都直…

HTTP与HTTPS的工作流程

HTTP与HTTPS的工作流程 http知识点回顾1、HTTP访问的过程2、HTTP常见状态码3、HTTP 协议一共五大特点 https的工作流程1、对称加密2、非对称加密3、https工作流程 http知识点回顾 1、HTTP访问的过程 &#xff08;1&#xff09;解析url&#xff0c;获取 url 中包含的域名&…

使用ffmpeg转换索尼老DV拍摄的VOB文件为mp4

一些背景故事 最近对象想用 CCD 拍照录像&#xff0c;家里刚好有一台快 20 年前的索尼 DV DCR-DVD653E&#xff0c;就是电池老化充不进去电了。 翻出来之后还感慨了一下&#xff1a;当年没有网购&#xff0c;价格不透明&#xff1b;有些地方也没有官方店&#xff0c;只有一两家…

vivado:关联notepad++

网上好多都要下插件&#xff0c;看了野火视频&#xff0c;直接在vivado里面加路径弄好的 2 3&#xff08;那个fonts and colors也经常用 改字体&#xff09; 4 5 以下是我的路径 D:/gongjuruanjian/notepad/Notepad/notepad.exe [file name] -n[line number] 把[file name] -…

【刷题】 leetcode 面试题 01.06 字符串压缩

字符串压缩 字符串压缩思路一&#xff08;双指针顺畅版&#xff09;思路二&#xff08;sprintf函数巧解版&#xff09; Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读下一篇文章见&#xff01;&#xff01;&#xff01; 字符串压缩 来看题目&#xff1a; 根据题目…

Python实现中英文互译

使用预训练模型时经常会涉及到中英文互译&#xff0c;总结一下方法 1、translate库 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple translate使用 #中文翻译成英文translator Translator(from_langchinese,to_langenglish)result translator.translate(&…

【QML-Qt Design Studio】

QML编程指南 ■ Qt Design Studio &#xff08;Qt Quick UI设计工具&#xff09;■ 安装Qt Design Studio■ ■ Qt Design Studio &#xff08;Qt Quick UI设计工具&#xff09; Qt Design Studio是一个用于创建酷炫、优美UI的工具。 简单概括其功能就是让UI设计转换为qml&…

[UI5 常用控件] 01.Text

文章目录 前言1. 普通文本2. 长文本&#xff1a;3. 设置最大显示行数 ( maxLines3 )4. 单行显示 ( wrappingfalse )5. 显示空白符 ( renderWhitespacetrue )6. 使用 - 连接单词:只适用于英文 ( wrappingTypeHyphenated )7. 空白时使用 - 代替 ( emptyIndicatorModeOn )8. JSON数…

数据采集与预处理02 :网络爬虫实战

数据采集与预处理02 &#xff1a;网络爬虫实战 爬虫基本知识 1 HTTP的理解 URL uniform resource locator. 是统一资源定位符&#xff0c;URI identifier是统一资源标识符。几乎所有的URI都是URL。 URL前部一般可以看到是HTTP还是HTTPS&#xff0c; 这是访问资源需要的协议…