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

如何在Django模型中避免Decimal字段自动四舍五入

Django中DecimalField截断小数位(不四舍五入)的实现方案

针对你遇到的金额保存自动四舍五入问题,以下是几种可行的实现方案,均能实现截断两位小数而非四舍五入的需求:

方法一:重写模型的save方法

直接在模型的save方法中对金额字段做预处理,确保保存前已完成截断:

from decimal import Decimal, ROUND_TRUNC
from django.db import models

class PerTransaction(models.Model):
    amount = models.DecimalField(default=0, max_digits=10, decimal_places=2, verbose_name="Transaction Amount")

    def save(self, *args, **kwargs):
        if self.amount is not None:
            # 使用ROUND_TRUNC模式截断到两位小数,不触发四舍五入
            self.amount = self.amount.quantize(Decimal('0.00'), rounding=ROUND_TRUNC)
        super().save(*args, **kwargs)

方法二:自定义可复用的截断Decimal字段

如果多个模型需要相同的截断逻辑,自定义字段可以避免重复代码,同时保证逻辑统一:

from decimal import Decimal, ROUND_TRUNC
from django.db import models

class TruncatedDecimalField(models.DecimalField):
    def pre_save(self, model_instance, add):
        value = getattr(model_instance, self.attname)
        if value is not None:
            # 根据字段定义的decimal_places动态生成格式字符串
            decimal_format = Decimal(f'0.{"0"*self.decimal_places}')
            value = value.quantize(decimal_format, rounding=ROUND_TRUNC)
            setattr(model_instance, self.attname, value)
        return super().pre_save(model_instance, add)

# 在模型中使用自定义字段
class PerTransaction(models.Model):
    amount = TruncatedDecimalField(default=0, max_digits=10, decimal_places=2, verbose_name="Transaction Amount")

方法三:在表单层处理(适用于用户输入场景)

如果金额是通过表单提交的,可以在表单的clean方法中提前处理数值,截断后再传入模型:

from decimal import Decimal, ROUND_TRUNC
from django import forms
from .models import PerTransaction

class PerTransactionForm(forms.ModelForm):
    class Meta:
        model = PerTransaction
        fields = ['amount']

    def clean_amount(self):
        amount = self.cleaned_data.get('amount')
        if amount:
            return amount.quantize(Decimal('0.00'), rounding=ROUND_TRUNC)
        return amount

关键注意点

PostgreSQL的numeric(10,2)类型默认会对超出两位的小数进行四舍五入,因此必须在Django层面完成截断处理后再存入数据库,才能确保最终存储的是截断后的值。

内容的提问来源于stack exchange,提问作者Purushottam Nawale

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:15:02