ORM调用mysql库函数,实现除法向下取整
·
导包
from django.db.models import Func, IntegerField
自定义 Django ORM 除法取整函数
以下提供两种自定义 Django ORM 函数的实现方案,分别实现向下取整除法和向上取整除法功能:
向下取整除法实现
class DivFloor(Func):
"""
向下取整除法:FLOOR(numerator / denominator)
使用示例:
queryset.annotate(result=DivFloor(F('field1'), F('field2')))
"""
function = 'FLOOR'
arity = 2
output_field = IntegerField()
def __init__(self, numerator, denominator, **extra):
expression = numerator / denominator
super(DivFloor, self).__init__(expression, **extra)
向上取整除法实现
class DivCeil(Func):
"""
向上取整除法:CEIL(numerator / denominator)
注意:arity=1 因为参数是除法表达式整体
"""
function = 'CEIL'
arity = 1
output_field = IntegerField()
def __init__(self, numerator, denominator, **extra):
expression = numerator / denominator
super(DivCeil, self).__init__(expression, **extra)
安全使用建议
为防止除零错误,推荐结合 Case/When 使用:
from django.db.models import Case, When, Value
safe_div = Case(
When(denominator=0, then=Value(0)), # 或其他默认值
default=DivFloor(numerator, denominator)
)
复杂表达式示例
支持在参数中使用复杂表达式:
# 计算 (field1 * field3) // field2
DivFloor(F('field1') * F('field3'), F('field2'))
# 计算 CEIL(field1 / (field2 + field3))
DivCeil(F('field1'), F('field2') + F('field3'))
# ↑ 被除数 ↑ 除数
数据库兼容性说明
- 该实现依赖数据库的 FLOOR 和 CEIL 函数
- MySQL、PostgreSQL、SQLite 均支持这些函数
- 不同数据库对除零处理可能不同,建议始终添加 Case/When 保护
更多推荐
所有评论(0)