当前位置: 首页 > 编程日记 > 正文

djangorestframework怎么这么好用!

一年前就已经用过restframework, 当时觉得这个只是给web框架打辅助的, 他能实现的我也都实现(可能没有那么好用, 嘿嘿)

但是我有一种东西叫做效率, 时间就是金钱, 别人造好的就直接用就可以了, 自己其实没必要在去重复.

最近写一个调查问卷系统, 利用了以下知识点

1. django

2. restframework(重点重点重点)

3. Vue

4. axios

5. ..............

从这个项目中我对restframework有了重新的认识, 互联网的精神就是共享, 所以就分享出来了

restframework的序列化器

当项目的架构为前后端分离时, 前后端的数据交互就变的尤为的重要, restframework的序列化过程无外乎一下6步:

1. 获取数据集合(queryset)

2. 获取序列化器

3. 过滤, 排序

4. 分页

5. 对处理好的数据进行进行序列化

5. 响应序列化结果

这些都是最基本的步骤, 但是在每一步中都蕴藏了大量的小技术, 利用这些小技术, 也许你正在头疼的一小问题就能找到答案, 哈哈, 细节决定成败

选择性的对字段进行序列化

官方是这样说的

For example, if you wanted to be able to set which fields should be used by a serializer at the point of initializing it, you could create a serializer class like so

王氏翻译: 例如,如果您希望能够在初始化序列化器时设置序列化器应该使用哪些字段,您可以创建这样的序列化器类:

这个类就长这样

class DynamicFieldsModelSerializer(serializers.ModelSerializer):"""A ModelSerializer that takes an additional `fields` argument thatcontrols which fields should be displayed."""def __init__(self, *args, **kwargs):# Don't pass the 'fields' arg up to the superclassfields = kwargs.pop('fields', None)# Instantiate the superclass normallysuper(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)if fields is not None:# Drop any fields that are not specified in the `fields` argument.allowed = set(fields)existing = set(self.fields)for field_name in existing - allowed:self.fields.pop(field_name)

之后你的序列化器就可以继承这个类了, 但是要注意这个类是在ModelSerializer之上的

下面就是使用方法

序列化器

class BookSerializers(DynamicFieldsModelSerializer):class Meta:model = models.Bookfields = "__all__"

在视图中使用序列化器

class TestView(APIView):def get(self, request, *args, **kwargs):queryset = models.Book.objects.all()serializer = serializers.BookSerializers(queryset, many=True, fields=("id", "title", "price"))# fields: 指定要序列化的字段return Response(serializer.data)

自定义field

虽然内置有很多的字段类型, 但是从实际的开发角度来说, 内置的都是一些普遍使用的字段, 再生产环境中结合实际问题, 那就需要我们自己定义字段了

现在就有一种实际需求

公司购买了多台CDN服务器, 从来存放图片等静态资源, 现在有一个问题, 假如某一天公司换了CDN, 那么之前代码中的图片链接都要修改一遍吗, 肯定不行

其实解决这个问题的方法有多种, 下面就使用自定义字段来解决这个问题

1. 创建一个自定义字段

class ImagePathField(fields.Field):def __init__(self, cdn_host, *args, **kwargs):super(ImagePathField, self).__init__(*args, **kwargs)self.cdn_host = cdn_host  # 封装CDN主机def to_representation(self, value):"""序列化时这个方法会被执行:param value::return:"""return "{}/{}".format(self.cdn_host, value)  # 构建完整的链接地址, 返回值将作为数据源def to_internal_value(self, data):pass

2. 在序列化器中使用自定义的字段

class BookSerializers(DynamicFieldsModelSerializer):title = fields.ImagePathField(settings.CND_HOST)  # 使用自定义的字段, 还可以传递source参数, 就相当于执行ORM, 写什么就对这个对象"."什么class Meta:model = models.Bookfields = "__all__"

3. 验证序列化结果

方法字段

除了上面的自定义字段, 还有一种方法字段方法字段, 这种字段也能够起到自定义的效果

1. 在序列化器中使用方法字段

class BookSerializers(DynamicFieldsModelSerializer):authors = serializers.SerializerMethodField()  # 使用方法字段class Meta:model = models.Bookfields = "__all__"def get_authors(self, value):"""对authors这个字段进行序列化时, 会调用get_字段这个方法, 这个方法的返回值将作为数据源:param value::return:"""author_str = ""for author in value.authors.all():author_str += "%s-%s " % (author.name, str(author.age))return author_str

2. 在视图中对数据进行序列化

class TestView(APIView):def get(self, request, *args, **kwargs):queryset = models.Book.objects.all()serializer = serializers.BookSerializers(queryset, many=True, fields=("id", "title", "price", "authors"))# fields: 指定要序列化的字段return Response(serializer.data)

3. 验证序列化结果

内置的时间字段 DateTimeField

在处理时间数据时, 让人头疼就是时间的格式, 不同的位置可能显示的格式不一样, 在DRF中内置了时间字段, 可以对时间数据做格式化

1. 在序列化器中使用时间字段

class BookSerializers(DynamicFieldsModelSerializer):pub_date = serializers.DateTimeField(format="%Y-%m-%d %X")  # 使用时间字段, 指定时间格式class Meta:model = models.Bookfields = "__all__"

2. 验证序列化结果

内置字符串字段  CharField

字符串是用的最多的数据类型, 当你需要从一个ORM对象关联的另外一种表中取某某一个字段时, 那么你就可以使用CharField

1. 在序列器中使用CharField

很重要的一个参数就是source, 他可以执行ORM操作

还有一个参数就会default, 可以给一个默认值

class BookSerializers(DynamicFieldsModelSerializer):publish = serializers.CharField(source="publish.address")   # source默认就是publish, 不需要写, 使用"."的方式进行ORM操作class Meta:model = models.Bookfields = "__all__"

2. 验证序列化结果

嵌套的序列化器

当表结构很深的时候, 构建数据往往是很麻烦的事情, 而且考虑到网络传输的效率问题, 还要尽量的减少无用的数据传输, 只传输必须的数据

这样一来就需要在序列化的时候下功夫了.

ORM有外键和多对多, 一对一等数据类型, 对比着序列化器, 就是序列化一个元素, 序列化多个元素而已

下面是我在调查问卷系统中的一个嵌套的序列化器

class ChoicesSerializer(DynamicFieldsModelSerializer):"""4. 用于获取问题所对应的选项的答案和答案所对应的分值的序列化器"""class Meta:model = models.SurveyChoicesfields = "__all__"class QuestionSerializer(DynamicFieldsModelSerializer):"""3. 获取问卷调查模板的所有问题"""survey = serializers.SerializerMethodField()survey_item = serializers.IntegerField(source="pk")choices = ChoicesSerializer(source="answers", many=True, fields=("content", "points"))  # fields: 指定要序列化的字段value = serializers.CharField(default="")error = serializers.CharField(default="")class Meta:model = models.SurveyItemfields = ("survey",  # 问题所属的调查问卷模板id"survey_item",  # 问题的id"name",  # 问题内容"answer_type",  # 问题的类型"choices",  # 如果是选择题, 对应的选项"value",  # 答案"error",  # 用作于提示的错误信息
        )def get_survey(self, instance):""":param instance::return:"""return self.context.get("survey_id")class SurveysSerializers(DynamicFieldsModelSerializer):"""2. 获取调查问卷使用的问卷模板"""questions = serializers.ListSerializer(child=QuestionSerializer())class Meta:model = models.Surveyfields = ("id",  # 问卷模板的id"name",  # 问卷模板的名称"questions",  # 该问卷模板关联的所有问题
        )def to_representation(self, instance):""":param instance::return:"""self.context["survey_id"] = instance.pkdata = super(SurveysSerializers, self).to_representation(instance)return dataclass GetQuestionnaireDetailSerializers(DynamicFieldsModelSerializer):"""1. 获取调查问卷详情页的序列化器的入口"""surveys = SurveysSerializers(many=True)class Meta:model = models.MiddleSurveyfields = ("name",  # 调查表的名字"surveys",  # 本次调查表使用的所有问题模板)

看着代码挺多, 其实套路都是一样

当要序列化的字段是一个外键关系时, 就给这个字段指定另外一个序列化器,

如果是多对多, 那么序列化器中就需要指定many=True, 否则就不用.

和正常的使用序列化器一样

上面说的是序列化, 还有反序列化, 同样可以使用嵌套序列化器

转载于:https://www.cnblogs.com/594504110python/p/10362674.html

相关文章:

第五百六十四天 how can I 坚持

变得越来越成熟了啊,放下的速度越来越快了。 我不会去羡慕那些亿万富翁,也不会去鄙视一个流浪汉,人人生而平等,just oncelife。 学会线代睡觉,晚上竟然又看起了不良人2.哎。转载于:https://www.cnblogs.com/52-it/p/60…

EOSIO Dawn 4.0 发布

链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 关于Dawn 4.0 RAM分配的反馈 一些社区成员表示担心,在其他任何人发现之前,有些人会通过购买便宜的内存来获得不合理的利润。…

shell脚本俄罗斯方块游戏

亲自测试了一个大牛写的shell脚本&#xff0c;感兴趣可以看看&#xff0c;效果如下&#xff1a; 代码如下&#xff1a; 1 #!/bin/bash2 3 # Tetris Game4 # 10.21.2003 xhchen<[email]xhchenwinbond.com.tw[/email]>5 6 #APP declaration7 APP_NAME"${0##*[\\/]}&…

python 虚拟现实_虚拟现实 | MOOC中国 - 慕课改变你,你改变世界

你将学到什么Discover the fundamentals of Virtual Reality, the hardware and history, different applications, and the psychology and challenges of the medium.Learn the basics of 3D graphics, how we create objects and how to lay them out to create an environm…

Linux常用开发环境软件-jdk安装

linux下安装jdk1.8版本 用rpm -qa | grep java查看rpm安装的jdk版本卸载openjdk[roothuangdanfeng ~]# rpm -e --nodeps tzdata-java-2016c-1.el6.noarch     [roothuangdanfeng ~]# rpm -e --nodeps java-1.7.0-openjdk-1.7.0.99-2.6.5.1.el6.x86_64     [roothuang…

EOS Cleos 命令使用指南

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 命令参考 操作 语法 例子 获取所有命令 $ cleos 例子 获取所有子命令 $ cleos ${command} 例子 链接节点 $ cleos --url node:{node}:no…

如何养出一个三十几亿身家的儿子

简评&#xff1a;他是 Atlassian 联合创始人&#xff08;$36亿&#xff09;的父亲&#xff0c;他以前是花旗银行和 IBM 的高管&#xff0c;是在澳大利亚设立花旗银行的那个人。晚饭时间饭桌上与孩子们聊的是「global issues」。 为了避免混淆&#xff0c;以下简称「父亲」和「儿…

jQuery学习- 内容选择器

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>内容选择器</title><script src"js/jquery.js"></script><script type"text/javascript">$(function(){//利用:contains获取包…

quickpcb添加pcb库_quickpcb使用说明

怎样抄板呢&#xff1f;抄板流程是怎样的&#xff1f;抄板比设计难度低得多&#xff0c;抄板&#xff0c;其实就是依葫芦画瓢。抄板步骤的简单说明&#xff1a;1.扫描电路板图片2.运行Quickpcb2005程序3.在文件菜单中调入扫描的电路板图片4.这个软件提供了测量工具和计算器&…

[mqtt]mqtt嵌入式移植

目前在无线这块&#xff0c;很多4G模组的厂商已经将mqtt放入模块内&#xff0c;无需在项目代码中再实现mqtt移植 github eclipse paho source code: https://github.com/mqtt/mqtt.github.io/wiki/libraries STM32 mqtt移植: http://sun2y.me/2017/05/12/MQTT%E5%8D%8F%E8%AE%A…

vue中点击第一次没有触发按钮怎么操作_vue如何触发某个元素的单击事件?

我来回答一波吧&#xff0c;&#xff0c;&#xff0c;因为没复习&#xff0c;&#xff0c;导致知识点结合不紧密。。。原生的中。。我们的写法是这样的王蒿大爷function myFunction(){document.getElementById("demo").innerHTML"Hello World";}window.οn…

微信小程序request合法域名怎么配置啊

request合法域名怎么配置啊&#xff0c; 有木有配置好的大神发来看看呀&#xff01; 用你申请小程序的后台账号&#xff0c;登录微信公众平台。然后点击设置&#xff0c;可配置服务器信息。<ignore_js_op>WechatIMG14.jpg (18.29 KB, 下载次数: 0) 登陆后 <ignore_js_…

全球比特币和区块链领域创业企业全景图

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 全球比特币和区块链创业企业中&#xff0c;美国的数量占全球55%&#xff0c;其次为英国占6%&#xff0c;新加坡占3%&#xff0c;中国仅占2%&#x…

iphone 在设置了initial-scale=1 之后,在设置滚动条之后,没有滑动效果的解决办法...

iphone在设置了initial-scale1 之后&#xff0c;我们终于可以以1:1 的比例进行页面设计了。 关于viewport&#xff0c;还有一个很重要的概念是&#xff1a;iphone 的safari 浏览器完全没有滚动条&#xff0c;而且不是简单的“隐藏滚动条”&#xff0c;是根本没有这个功能。 iph…

python入门小练习_python入门题目小练

Q1:Return the number (count) of vowels in the given string.We will consider a, e, i, o, and u as vowels for this Kata.The input string will only consist of lower case letters and/or spaces.也就是返回给定字符串中的元音字母(a, e, i, o, u)个数。分析&#xff1…

Cookie 用法

//Cookie:是一个客户端状态保持机制&#xff0c;&#xff08;网站的数据是存在客户端&#xff09;&#xff0c;与隐藏域与ViewState对象都属于这种客户端状态保持&#xff0c;Cookie中存储的是关于网站相关的文本字符串数据。Cookie的存储方式有两种&#xff0c;如果不指定过期…

比特币vs分布式账本vs以太坊vs区块链

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 我们经常被告知&#xff0c;区块链 - 比特币背后的技术 - 不仅将重新布线银行业&#xff0c;还包括社会保障支付&#xff0c;医疗保健甚至数字投票…

git 修改标签名称_Git常用命令汇总,希望能帮到你

展示帮助信息git help -g回到远程仓库的状态抛弃本地所有的修改&#xff0c;回到远程仓库的状态。git fetch --all && git reset --hard origin/master重设第一个commit也就是把所有的改动都重新放回工作区&#xff0c;并清空所有的commit&#xff0c;这样就可以重新提…

js字符串去重

js字符串去重&#xff1a; 1、 去掉字符串前后所有空格&#xff1a; function Trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); }说明&#xff1a; 如果使用jQuery直接使用$.trim(str)方法即可&#xff0c;str表示要去掉前后所有空格的字符串。 2、 去掉字…

JavaScript-也来谈--闭包

闭包&#xff0c;以前研究过&#xff0c;可能是当初理解的不够透彻&#xff0c;现在又忘了&#xff0c;(给自己一个台阶下-...)毕竟js一直没怎么用&#xff0c; 为了防止自己过段时间再忘了&#xff0c;写篇重要的闭包重点&#xff0c; 这样时不时也能温习下知识&#xff0c;不…

ABS是啥,为什么区块链可以与它完美结合?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 房地产市场在各方调控下终于进入新的平稳期&#xff0c;但租房市场近日来却是水涨船高。抛开传统的租售比概念不谈&#xff0c;今天小编想和大家谈…

Python学习笔记——全局变量声明

最近在编写python程序时发现&#xff0c;在函数中可以对函数外面的全局变量进行读取、打印等操作&#xff0c;但是不能赋值&#xff0c;否则会报错&#xff1a;UnboundLocalError: local variable a referenced before assignment示例代码如下&#xff1a;a 0def fun():print(…

发那科机器人示教器电缆线_云和发那科机器人维修

广州友仪机电设备有限公司创立于2007年&#xff0c;成长在自动化行业高速发展的高铁上&#xff0c;现在已经成为华南地区具影响力的工控维修品牌&#xff0c;2015年我们再出发&#xff0c;组织公司精英力量设立机器人项目事业部&#xff0c;投入大量经费购入四大家族的主力机型…

HDU 5729 Rigid Frameworks(连通性DP)

【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid5729 【题目大意】 给出一个n*m的方格框&#xff0c;可以在单位矩形中添加两种对角线的线&#xff0c;使得其变得稳定&#xff0c;问使得其变成稳定图形的方案数。 【题解】 稳定状态指的是在n*m范围内每行每列都有一个…

区块链+5G=智慧城市?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 智慧城市是一个非常大的产业范畴&#xff0c;同时包括面向政府的智慧治理、面向市民的智慧民生和面向产业的智慧经济三大板块&#xff0c;涵盖了智…

Vue - 表单

表单输入绑定 用 v-model 指令在表单 <input> 及 <textarea> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇&#xff0c;但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据&#xff0c;并对一些极端场景…

.NET 获取客户端的操作系统版本、浏览器版本和IP地址

我们在使用.NET做网站的时候&#xff0c;很多情况下需要需要知道客户端的操作系统版本和浏览器版本&#xff0c;怎样获取客户端的操作系统和浏览器版本呢&#xff1f;我们可以通过分析UserAgent来获取。 .NET 获取客户端的操作系统 请看下面的代码&#xff0c;我们首先创建一个…

android evaluater_android – 带有test.R.java的Robolectric

我在API21上有一个使用robolectric 3.0的库项目,com.android.tools.build&#xff1a;grad&#xff1a;1.3.1.我想在robolectric测试中使用测试资源(好像在src / androidTest / res / …下),即com.mypackage.test.R.java(而不是用于生产的com.mypackage.R.java).到目前为止我所…

比特币区块的产生速度为何被设定为10分钟?

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自区块链技术社区&#xff0c;未经允许拒绝转载。 众所周知&#xff0c;比特币的block产生速度被设定为了10分钟&#xff0c;按着官方wiki所说&#xff0c;每一个节点需要一些时间来确认block(<1…

PAT Advanced Level 1010

1010 Radix (25)&#xff08;25 分&#xff09; Given a pair of positive integers, for example, 6 and 110, can this equation 6 110 be true? The answer is "yes", if 6 is a decimal number and 110 is a binary number. Now for any pair of positive inte…