如何在Django注解中用Substr与负值截取字段末尾两位字符?
解决Django Substr注解取字段最后两位返回空的问题
嘿,我刚好踩过这个坑!Django的Substr函数第三个参数是长度值,它并不支持像某些原生数据库函数那样用负值表示从末尾截取,所以你直接传-2会被识别为无效参数,自然返回空字符串啦。
这里给你两种靠谱的解决方法:
方法一:结合Length函数计算起始位置
通过Length先获取目标字段的总长度,再计算出截取最后两位的起始位置(因为Django的Substr是1-based索引):
from django.db.models import Length, Substr Person.objects.all().annotate( code=Substr('str', Length('str') - 1, 2) )
举个例子:如果str字段值是"ABCDE",Length('str')返回5,起始位置就是5-1=4,从第4位开始取2个字符,结果就是"DE",完美拿到最后两位。
方法二:使用数据库原生的RIGHT函数(更简洁)
大多数数据库(比如MySQL、PostgreSQL、SQL Server)都支持RIGHT(str, length)函数,直接返回字符串右侧指定长度的内容。我们可以用Django的Func类封装这个函数:
from django.db.models import Func, F class Right(Func): function = 'RIGHT' arity = 2 # 表示这个函数接受2个参数 Person.objects.all().annotate( code=Right(F('str'), 2) )
这个方法更直观,而且不需要计算长度,直接告诉数据库取右边2个字符就行。
额外提醒
如果你的字段可能存在长度小于2的情况(比如空字符串、单字符),可以结合CaseWhen做兼容处理,避免返回异常:
from django.db.models import Case, When, Value, Length, Substr from django.db import models Person.objects.all().annotate( code=Case( When(Length('str') >= 2, then=Substr('str', Length('str') - 1, 2)), default=F('str'), output_field=models.CharField() ) )
内容的提问来源于stack exchange,提问作者Azee
相关产品推荐
相关产品推荐

