本文首发于公众号: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 Concat
from django.db.models import CharField, Value
from 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 CharField
from 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 CharField
from 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 LPad
from 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 Replace
from 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 StrIndex
from 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 系统操作的数据库优化做一次汇总。

如果想获取更多后端相关文章,可扫码关注阅读:

Django笔记二十七之数据库函数之文本函数的更多相关文章

  1. django笔记二之数据库

    django笔记二之数据库 [同步数据库之前的操作] yum install MySQL-python.x86_64 -y 2)开启数据库服务并创建表 创建数据库设置 为utf8: create da ...

  2. openresty 学习笔记二:获取请求数据

    openresty 学习笔记二:获取请求数据 openresty 获取POST或者GET的请求参数.这个是要用openresty 做接口必须要做的事情.这里分几种类型:GET,POST(urlenco ...

  3. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

  4. Android笔记二十七.Service组件入门(一).什么是Service?

    转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Service 1.Service简单介绍     Service为Android四大组件之中 ...

  5. Mysql完全手册(笔记二,使用数据与性能优化)

    一.使用数据 1.使用变量 MySQL也可以让我们以用户自定义的变量来存储select查询的结果,以便在将来select查询中使用.它们只会在客户会话期间存在,但是它们提供一个方便有效的方法来连接查询 ...

  6. 【Django笔记二】Django2.0配置模板和静态文件

    一.环境版本信息: 操作系统:windows10 Django版本:2.0.5 Python版本:3.6.4 二.创建模板 1.在my_project文件夹下新建文件夹templates用于存放模板文 ...

  7. django笔记(二)

    Model many-to-many可以通过through来定义详细信息. 表结构: property django可以用F和Q来配合查找,F可以用于同一个model不同field之间进行比较,可以对 ...

  8. Java基础学习笔记二十七 DBUtils和连接池

    DBUtils 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils.DBUtils就是JDBC的简化开发 ...

  9. 论文阅读笔记二十七:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks(CVPR 2016)

    论文源址:https://arxiv.org/abs/1506.01497 tensorflow代码:https://github.com/endernewton/tf-faster-rcnn 室友对 ...

  10. angular学习笔记(二十七)-$http(5)-使用$http构建RESTful架构

    在angular中有一个特别为RESTful架构而定制的服务,是在$http的基础上进行了封装. 但是为了学习,我们先看看用直接$http是如何构建RESTful架构的: 假设有一个银行卡的列表.需要 ...

随机推荐

  1. Android Studio查看指定APP日志

    1.启动Android Studio 2.View->Tool Windows->Terminal   3.在底部输入monitor 4.Android Devices Monitor新窗 ...

  2. elasticsearch开发学习及踩坑实录

    1.elasticsearch7.+需要jdk11 / elasticsearch6.+需要jdk8 , 如果是Java开发的同学本地开发使用jdk8 , 可以下载一个解压版的jdk11 , 然后修改 ...

  3. bash transpose csv

    transpose() { awk ' BEGIN { FS = ","; OFS = ","; } { if (max_nf<NF) max_nf=NF ...

  4. 前端复习之jQuery大全

    Jquery知识点梳理 梳理图摘自--https://www.cnblogs.com/859630097com/p/14433611.html [手机版]横屏观看,效果更佳 JavaScript类库: ...

  5. pod进阶

    一.Lifecycle 官网:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/ 通过前面的分享,关于pod是什么相信看 ...

  6. MobaXterm注册认证版,亲测可用,操作简单(本机已安装python3环境)

    去github地址下下载代码 解压后在该目录下打开CMD 执行MobaXterm-Keygen.py <UserName> <Version>命令 生成的文件放在安装目录下,我 ...

  7. linux : root  密码忘记,解决办法

    1.重启 2.在启动选择系统内核界面,按e键进入单用户模式 3.找到linux16(或者linux) 开头行,删除ro,并且在ro处添加 rw init=/sysroot/bin/sh 4.按 ctr ...

  8. 【攻防世界】web练习区write up

    目录: view_source robots backup cookie disabled button weak auth simple php xff referer webshell get p ...

  9. 性能的极致,Rust的加持,Zed-Dev编辑器快速搭建Python3.10开发环境

    快就一个字,甚至比以快著称于世的Sublime 4编辑器都快,这就是Zed.dev编辑器.其底层由 Rust 编写,比基于Electron技术微软开源的编辑器VSCode快一倍有余,性能上无出其右,同 ...

  10. Go内存管理逃逸分析

    1. 前言 所谓的逃逸分析(Escape analysis)是指由编译器决定内存分配的位置吗不需要程序员指定. 函数中申请一个新的对象 如果分配在栈中, 则函数执行结束后可自动将内存回收 如果分配在堆 ...