本文首发于公众号:Hunter后端原文链接:Django笔记二十四之数据库函数之比较和转换函数
这一篇笔记开始介绍几种数据库函数,以下是几种函数及其作用
【资料图】
这一篇笔记我们主要用到 Author 和 Entry model 作为示例,下面的是 Author model:
class Author(models.Model): name = models.CharField(max_length=200) email = models.EmailField(null=True, default=None) age = models.IntegerField(null=True, blank=True) alias = models.CharField(max_length=50, null=True, blank=True) goes_by = models.CharField(max_length=50, null=True, blank=True)
一般来说,对于 CharField 字段,我们是不推荐允许 null=True 存在的,因为这样的话,在数据库中就会存在两个空值,一个是 null,一个是空字符串 ""。
在这里允许这样操作是为了方便的介绍下面的功能。
注意下,数据库相关函数都是在 django.db.models.functions 模块下
2、Cast 转换类型Cast 的作用,我们可以将其理解成转换数据类型,比如在 Author 中,age 字段是一个 Integer 数据。
但是如果我们想要获取数据的时候想要将其直接变成浮点型数据,就可以使用 Cast() 函数,通过 output_field=FloatField() 参数来指定输出类型。
# 先创建数据from blog.models import AuthorAuthor.objects.create(name="hunter", age=25)
返回一个新字段,通过 Cast() 函数来指定输出类型:
from django.db.models import FloatFieldfrom django.db.models.functions import Castauthor = Author.objects.annotate(float_age=Cast("age", output_field=FloatField())).get(id=1)print(author.float_age)
最后的输出就是一个浮点型数据了。
3、Coalesce 优先取值Coalesce 的单词的含义是 合并、联合,但是在这里函数表现出的意义是,优先取值。
Coalesce() 接受多个字段或者表达式作为参数,至少为两个字段名称,然后会返回第一个非 null 的字段的值(注意:空字符串 "" 不被认为是 null 值)
每个元素都必须是相似的类型,否则会引起报错。
对于 Author 这个model,我们想要按照 alias, goes_by, name 三个字段的这个顺序来取值。
也就是说 有alias 字段就取 alias 的内容,否则取 goes_by 的字段值,goes_by 也没有 就取 name 字段,这种情况就可以使用 Coalesce() 来操作。
先来创建几条数据:
Author.objects.create(alias="alias-1", goes_by="goes-by-1", name="name-1")Author.objects.create(goes_by="goes-by-2", name="name-2")Author.objects.create(name="name-3")Author.objects.create(alias="", goes_by="goes-by-4", name="name-4")
以上三条数据的 id 在数据库分别是 2,3,4,5
接下来可以测试一下 Coalesce() 这个函数
from django.db.models.functions import Coalesceauthor = Author.objects.annotate(new_field=Coalesce("alias", "goes_by", "name")).get(id=2)print(author.new_field)# 输出 alias-1author = Author.objects.annotate(new_field=Coalesce("alias", "goes_by", "name")).get(id=3)print(author.new_field)# 输出 goes-by-2author = Author.objects.annotate(new_field=Coalesce("alias", "goes_by", "name")).get(id=4)print(author.new_field)# 输出 name-3author = Author.objects.annotate(new_field=Coalesce("alias", "goes_by", "name")).get(id=5)print(author.new_field)# 输出 空字符串 ""
以上几个例子,我们就测试出了新建字段的取值优先顺序,以及空字符串和 null 在这个函数里的区别(会跳过值为 null 的数据,但是会取空字符串的字段值)。
空值的默认值
其实用到这里,我们可以发现这个函数的另一个用法,那就是 null 值下替换的默认值。
假设我们有一个字段,我们在取值的时候,想实现,如果该字段是 null,那么我们在取值的时候就想将其替换成另一个默认值,而不是返回 null 或者后续在内存中操作替换默认值,可以这样操作:
from django.db.models import Valueauthor = Author.objects.annotate(new_field=Coalesce("email", Value("xxx"))).get(id=5)print(author.new_field)# id 等于 5 的 Author 数据,email 字段为空,所以 new_field 的值被替换成了 "xxx"
默认值的处理也可以用在聚合中,比如聚合 Sum() 的时候,如果没有满足条件的数据,聚合的结果会是一个 null,但是我们可以自动将其变为 0:
from django.db.models import Sum, ValueAuthor.objects.aggregate(age_sum=Coalesce(Sum("age"), Value(0)))
4、Greatest 返回较大值Greatest() 的用法与 Coalesce 相同,接受两个或多个类型相同的元素,返回最大的一个。
可以比较数字,和时间等字段类型。
这里示例我们使用 Entry model,我们只用两个整型字段:
class Entry(models.Model): number_of_comments = models.IntegerField() number_of_pingbacks = models.IntegerField()
用法如下:
from blog.models import Entryfrom django.db.models.functions import GreatestEntry.objects.annotate(max_value=Greatest("number_of_comments", "number_of_pingbacks")).get(id=2).max_value# max_value 字段取值就会是number_of_comments 和 number_of_pingbacks 之间最大的
这里我们也可以挖掘出一个骚操作,那就是取值的下限
比如这两个字段的值都没有达到我们想要的阈值,比如说是2,我们希望返回的值至少是2,可以这样设计程序:
Entry.objects.annotate(max_value=Greatest("number_of_comments", "number_of_pingbacks", Value(2))).get(id=2).max_value
注意:在MySQL 和 Oracle 中,如果 Greatest 中,只要有一个字段值为 null,那么结果就会返回 null,这一点一定要注意
Least() 这个取的是最小值,与 Greatest 作用是相反的,但用法是一样的,不多介绍
5、Nullif 值相同返回 None获取两个字段,也可以是表达式的结果,或者是 Value() 的值,但两者的数据类型得一致,用于判断两者的值是否相同。
如果两者的值相同,则返回 Python 里的 None,不相同的话返回第一个表达式的值
用法示例如下:
Entry.objects.annotate(new_field=NullIf("number_of_comments", "number_of_pingbacks")).get(id=1).new_fieldEntry.objects.annotate(new_field=NullIf("number_of_comments", Value(2))).get(id=1).new_field
以上就是本篇笔记全部内容,下一篇将介绍数据库函数之日期函数
如果想获取更多后端相关文章,可扫码关注阅读:
标签:
精彩推荐
5月20日是网络情人节,郑州陈寨花卉市场的一家花店看到一束与众不同的花,竟是用15个钢丝球包扎的。花店...
相较于火车站,机场的免费Wi-Fi速度要快了不少,而全球最快的免费Wi-Fi机场名单,也被统计了出来。美国...
近日,山东省高级人民法院向社会通报全省法院消费者权益司法保护工作情况及10起典型案例。据了解,五年...
南京市19日通报,公安部门在疫情防控期间依法打击各类涉疫违法犯罪行为,截至3月18日,全市共查处各类涉...
日前,北京市人民政府新闻办公室举行新闻发布会,解读《北京市全民科学素质行动规划纲要(2021—2035年)...
去年下半年以来,受多重因素影响,房地产市场出现下行态势。今年以来,各方共同努力持续稳地价、稳房价...
联合国人权理事会第49届会议新疆经济社会发展与人权保障边会18日在广州举办。会议由中国人权研究会、中...
人力资源和社会保障部近日印发《关于开展技术技能类山寨证书专项治理工作的通知》(以下简称《通知》),...
针对网络消费乱象,最高人民法院近期发布《最高人民法院关于审理网络消费纠纷案件适用法律若干问题的规...
当好农民工的“护薪人” 近日,罗某等7名农民工在收到被拖欠的工资后,纷纷打电话向江西省南昌市...
“通讯录里所有人都知道我欠钱了” □ 本报记者 韩丹东 □ 本报见习记者 张守坤 ...
大连宝马车撞人案肇事司机被判死刑 本报讯 记者韩宇 10月29日,辽宁省大连市中级人民法院一审...
医院财务迷上网络赌博输光5000万元公款 □ 本报记者 马维博 □ 本报通讯员 汪宇堂 曹...
辊环车削 雕琢毫厘(工匠绝活) 【绝活看点】 23年来,雷虎始终扎根一线,改进钢材轧制工艺...
交警严查超标电动自行车挪用“白牌” 截至昨晚6时,处罚电动自行车违法行为共计6585笔;下一步将...
明起寒潮来袭 北方气温普降10℃以上 中央气象台预计,本周日北京平原地区最低气温降至-4℃左右...
多种蔬菜价格降幅达五成 包括菠菜、蒿子秆等 预计本月中旬蔬菜恢复供需平衡 本报讯(记者...
北京周日最低气温或达-4℃ 本报讯(记者 赵婷婷)北京青年报记者昨天从中央气象台获悉,新一股...
昌平一家四口确诊新冠肺炎 天通北苑第二社区升级为中风险地区 朝阳两涉疫校区及16所学校停课 ...
人社部发布通知 事业单位招聘可适当降低学历要求 昨日,人社部发布《关于职业院校毕业生参加...
资讯News
04-19
04-19
04-19
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
04-18
聚焦Policy
当好农民工的“护薪人” 近日,罗某等7名农民工在收到被拖欠的工资后,纷纷打电话向江西省南昌市...
“通讯录里所有人都知道我欠钱了” □ 本报记者 韩丹东 □ 本报见习记者 张守坤 ...
大连宝马车撞人案肇事司机被判死刑 本报讯 记者韩宇 10月29日,辽宁省大连市中级人民法院一审...
医院财务迷上网络赌博输光5000万元公款 □ 本报记者 马维博 □ 本报通讯员 汪宇堂 曹...
辊环车削 雕琢毫厘(工匠绝活) 【绝活看点】 23年来,雷虎始终扎根一线,改进钢材轧制工艺...
交警严查超标电动自行车挪用“白牌” 截至昨晚6时,处罚电动自行车违法行为共计6585笔;下一步将...
明起寒潮来袭 北方气温普降10℃以上 中央气象台预计,本周日北京平原地区最低气温降至-4℃左右...
多种蔬菜价格降幅达五成 包括菠菜、蒿子秆等 预计本月中旬蔬菜恢复供需平衡 本报讯(记者...
北京周日最低气温或达-4℃ 本报讯(记者 赵婷婷)北京青年报记者昨天从中央气象台获悉,新一股...
昌平一家四口确诊新冠肺炎 天通北苑第二社区升级为中风险地区 朝阳两涉疫校区及16所学校停课 ...