本文首發于公眾號:Hunter后端
原文鏈接:Django筆記二十七之資料庫函式之文本函式
這篇筆記將介紹如何使用資料庫函式里的文本函式,
顧名思義,文本函式,就是針對文本欄位進行操作的函式,如下是目錄匯總:
- Concat() —— 合并
- Left() —— 從左邊開始截取
- Length() —— 獲取字串長度
- Lower() —— 小寫處理
- LPad() —— 從左邊填充指定字串
- MD5() —— 獲取字串MD5哈希值
- Repeat() —— 重復指定欄位值
- Replace() —— 替換指定內容
- Reverse() —— 欄位內容反轉回傳
- StrIndex() —— 獲取第一個匹配指定字串的下標
- SubStr() —— 字串截取
- 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 系統操作的資料庫優化做一次匯總,
如果想獲取更多后端相關文章,可掃碼關注閱讀:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/550780.html
標籤:其他
上一篇:Rust中的Copy和Clone
下一篇:返回列表
