You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:02:55