写点什么

Django 笔记二十七之数据库函数之文本函数

作者:Hunter熊
  • 2023-05-13
    北京
  • 本文字数:4181 字

    阅读完需:约 14 分钟

Django笔记二十七之数据库函数之文本函数

本文首发于公众号:Hunter 后端

原文链接:Django笔记二十七之数据库函数之文本函数


这篇笔记将介绍如何使用数据库函数里的文本函数。


顾名思义,文本函数,就是针对文本字段进行操作的函数,如下是目录汇总:


  1. Concat() —— 合并

  2. Left() —— 从左边开始截取

  3. Length() —— 获取字符串长度

  4. Lower() —— 小写处理

  5. LPad() —— 从左边填充指定字符串

  6. MD5() —— 获取字符串 MD5 哈希值

  7. Repeat() —— 重复指定字段值

  8. Replace() —— 替换指定内容

  9. Reverse() —— 字段内容反转返回

  10. StrIndex() —— 获取第一个匹配指定字符串的下标

  11. SubStr() —— 字符串截取

  12. Trim() —— 去除给定字段空格


这一篇笔记记录的函数有点多,可以慢慢看,慢慢测试,其中有一些函数是左右都有对应操作的,我这里只介绍一个,另一个对应的函数除了函数名不一样和作用相反外,用法都是一样的。


我们这次用到的是 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)
复制代码

1、Concat() —— 合并

Concat() 函数,是合并的作用,接受至少两个文本字段或者表达式参数,将其合并成一个字段返回。


示例如下:


from django.db.models.functions import Concatfrom django.db.models import CharField, Valuefrom blog.models import Author
author = Author.objects.create(name="hunter", alias="alias")

author = Author.objects.annotate( concat_name=Concat('name', Value('_'), 'alias', output_field=CharField() )).get(id=author.id)

print(author.concat_name)
复制代码


在示例中,我们将 name 字段和 alias 字段以及 _ 这个字符串用 Value() 函数修饰,传入 Concat(),并通过 output_field 来指定输出字符串类型,将三者合并成一个字符串返回


注意: 如果是将 TextField() 和 CharField() 字段进行合并,那么 output_field 必须是 TextField()

2、Left() —— 从左边开始截取

输入两个参数,一个是指定字段,一个是指定的长度,表示将对该字段从左边开始截取指定长度返回


以下是示例:


from django.db.models.functions import Left
author = Author.objects.annotate(left_three_str=Left('name', 3)).get(id=10)
print(author.left_three_str)
复制代码


注意一下,我在示例中使用到的 id 的值都是在我自己数据库的 id 值,读者在自己测试的时候,需要替换成自己数据的真实 id


同理,django.db.models.functions.Right 是从右边开始截取

3、Length() —— 获取字符串长度

接受文本字段或者表达式作为参数,返回字符串长度


如果字段或者表达式为 null,那么在 Python 里会返回 None


以下是使用示例:


from django.db.models.functions import Length
author = Author.objects.annotate(name_length=Length("name"), email_length=Length("email")).get(id=10)
print(author.name_length)# 返回数字
print(author.email_length)# 字段值为 null, 所以返回 None
复制代码


这里也可以用于搜索,假设说我想搜索 name 字段长度大于 3 的数据,可以如下实现:


from django.db.models import CharFieldfrom django.db.models.functions import Length
CharField.register_lookup(Length)
authors = Author.objects.filter(name__length__gt=3)print(authors.count())
复制代码


或者 annotate() 出一个新字段,然后进行 filter()


Author.objects.annotate(name_length=Length("name")).filter(name_length__gt=3)
复制代码

4、Lower() —— 小写处理

接受文本字段名或者表达式作为参数传入,然后将其小写化处理返回


以下是使用示例:


from django.db.models.functions import Lower
Author.objects.create(name="HUNTER")
author = Author.objects.annotate(name_lower=Lower("name")).get(id=11)
print(author.name_lower)
复制代码


跟 Length() 函数一样,也可以使用注册的方式来搜索:


from django.db.models import CharFieldfrom django.db.models.functions import Lower
CharField.register_lookup(Lower)
authors = Author.objects.filter(name__lower="hunter")print(authors.values("name"))
复制代码


同理,大写化的函数为 django.db.models.functions.Upper()

5、LPad() —— 从左边填充指定字符串

LPad() 意思为从左边填充指定字符串,接受三个参数:


第一个参数为字段名或表达式


第二个参数为需要填充到的长度,参数名为 length,需要指定值


第三个参数名为 fill_text,值为填充的内容,默认为空字符串


假设我们需要将 abc 填充到 name 字段,需要填充到 10 个字符长度


那么如果 name 的原始值为 hunter,结果则会是 abcahunter


如果需要填充的值短了,那么就会重复填充,如果长了,就会被截取填充,在刚刚的例子里,第二次填充的时候,再重复一次 abc 则超出 10 个长度的限制,所以 abc 被截取了。


以下是使用示例:


from django.db.models.functions import LPadfrom django.db.models import Value
Author.objects.create(name="HUNTER")
author = Author.objects.annotate( name_1=LPad('name', 4, fill_text=Value('abc')), name_2=LPad('name', 8, fill_text=Value('abc')), name_3=LPad('name', 16, fill_text=Value('abc'))).get(id=11)

print(author.name_1)# HUNT
print(author.name_2)# abHUNTER
print(author.name_3)# abcabcabcaHUNTER
复制代码


更新操作


我们还可以利用 LPad() 函数来对字段进行更新操作


Author.objects.filter(id=11).update(name=LPad('name', 10, Value('abv')))author = Author.objects.get(id=11)print(author.name)
复制代码


这段代码的含义为,将 name 字段原有值的左边填充 abc 字符串填充到 10 个字符长度后更新到 name 字段


同理,还有一个从右边开始填充的函数 RPad(),也是同样的用法

6、MD5() —— 获取字符串 MD5 哈希值

接受单个文本字段或者表达式作为参数,返回字符串的 MD5 哈希值


from django.db.models.functions import MD5
author = Author.objects.annotate(name_md5=MD5('name')).get(id=11)
print(author.name_md5)
复制代码

7、Repeat() —— 重复指定字段值

Repeat(expression, number)接受字段参数,和重复的次数,返回字段内容重复 number 遍之后的数据


from django.db.models.functions import Repeat
Author.objects.create(name="Python")# id = 13
author = Author.objects.annotate(repeat_name=Repeat("name", 3)).get(id=13)print(author.repeat_name)
# 打印出的值为:PythonPythonPython
复制代码


更新字段数据


将 id=13 的数据的 name 字段重复三遍之后更新到该字段:


Author.objects.filter(id=13).update(name=Repeat("name", 3))
复制代码

8、Replace() —— 替换指定内容

Replace(expression, text, replacement=Value(''))替换,即将 expression 字段的值的所有内容为 text 的替换成 replacement 的内容,replacement 默认为空字符串


在下面的例子中,我们将 name 字段中所有的 Ma 字符串更新为 Je


from django.db.models.functions import Replacefrom django.db.models import Value
Author.objects.create(name="Match-Mary")# id = 14
Author.objects.filter(id=14).update(name=Replace('name', Value('Ma'), Value('Je')))
author = Author.objects.get(id=14)
print(author.name)# Jetch-Jery
复制代码

9、Reverse() —— 字段内容反转返回

接受字段或者表达式为参数,将原字段内容倒序后返回


from django.db.models.functions import Reverse
author = Author.objects.annotate(reverse_name=Reverse('name')).get(id=11)print(author.reverse_name)
复制代码

10、StrIndex() —— 获取第一个匹配指定字符串的下标

接受两个参数,一个参数为字段名,第二个参数为需要匹配的子串


如果子串在字段中被匹配上了,将会返回第一个匹配上的子串的下标


注意 1:匹配上的下标是从 1 开始计数的,如果没有匹配上,那就回返回 0


注意 2:这个匹配的过程是忽略大小写的


from django.db.models.functions import StrIndexfrom django.db.models import Value
author = Author.objects.create(name="thIs is a Test")
author = Author.objects.annotate( is_index=StrIndex("name", Value("is")), test_index=StrIndex("name", Value("test")), xx_index=StrIndex("name", Value("xx"))).get(id=author.id)

print(author.is_index)# 3,is 字符串匹配忽略大小写,下标从1开始,所以是3
print(author.test_index)# 11
print(author.xx_index)# 0 找不到对应的字符串,所以返回 0,可以根据 0 这个标志位来判断字段中是否包含某个特定字符
复制代码


而这个操作我们可以用来筛选字段中是否包含某个特定字符串的数据,根据返回的结果是否为 0 来判断:


authors = Author.objects.annotate(ter_index=StrIndex("name", Value("ter"))).filter(ter_index__gt=0)print(authors.count())
复制代码

11、SubStr() —— 字符串截取

SunStr(expression, pos, length=None)


这是一个字符串截取的函数,给定一个字段名,和开始的下标(下标从 1 开始计数),和需要计数的长度


表示将某字段,从指定下标开始,截取指定长度的字符串



from django.db.models.functions import Substr
# 将 name 字段 从 第二个字符开始往后截取三个长度的字符author = Author.objects.annotate(name_sub_str=Substr('name', 2, 3)).get(id=12)
print(author.name_sub_str)
复制代码


可以用于直接更新:


Author.objects.filter(id=12).update(name=Substr('name', 2, 3))
复制代码

12、Trim() —— 去除给定字段空格

去除空格给定字段左右两边的空格


Author.objects.create(name=" test trim ")  # id = 15
from django.db.models.functions import Trim
author = Author.objects.annotate(trim_name=Trim("name")).get(id=15)
print(author.trim_name)
复制代码


也可以直接用于更新:


Author.objects.filter(id=15).update(name=Trim("name"))
复制代码


同理,还有去除左边空格的函数 LTrim() 和 去除右边空格的函数 RTrim()


以上就是本篇笔记全部内容,下一篇将会是比较重要也比较长的一篇笔记,将会对 Django 系统操作的数据库优化做一次汇总。

发布于: 刚刚阅读数: 4
用户头像

Hunter熊

关注

公众号:Hunter后端 2018-09-17 加入

Python后端工程师,欢迎互相沟通交流

评论

发布
暂无评论
Django笔记二十七之数据库函数之文本函数_Python_Hunter熊_InfoQ写作社区