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

Django模型如何同时准确存储整数与浮点数且不做自动转换?

实现方案

你当前使用的IntegerField(原代码拼写错误为IntegerFiled)仅支持存储整数,写入浮点数时会被自动截断,无法满足需求。推荐以下两种实现方案,可根据实际场景选择:

方案1:使用DecimalField(最推荐,无精度损失)

Django的DecimalField基于Python的Decimal类型实现,不会出现二进制浮点数的精度丢失问题,同时支持存储整数和小数,不会强制做类型转换:

模型修改代码

from django.db import models
from decimal import Decimal

class MachineStatus(models.Model):
    # max_digits代表总位数(含小数位),decimal_places代表小数位最大长度
    # 可根据实际温度精度、范围需求调整,比如需要支持两位小数就设置decimal_places=2
    heat = models.DecimalField(max_digits=5, decimal_places=1, default=0, null=True, blank=True)
    
    # 可选扩展:添加属性自动返回对应原生类型(整数返回int,小数返回float)
    @property
    def heat_value(self):
        if self.heat is None:
            return None
        if self.heat == int(self.heat):
            return int(self.heat)
        # 要保留Decimal高精度类型直接返回self.heat即可,无需转float
        return float(self.heat)

写入整数6时会存储为Decimal('6'),写入6.5时存储为Decimal('6.5'),通过heat_value取值即可自动返回对应类型的数值,完全符合不自动转换、保持精度的要求。

方案2:使用JSONField(需要数据库层存储原生int/float类型时使用)

如果你需要数据库层面直接存储原生的int和float类型,不需要Decimal的额外封装,可以使用JSONField实现:

模型修改代码

from django.db import models

class MachineStatus(models.Model):
    heat = models.JSONField(default=0, null=True, blank=True)

写入时直接传int类型的6或者float类型的6.5即可,读取时会直接返回对应类型的数值,不会做任何自动转换。缺点是JSONField无法直接做数值范围、类型校验,需要自行重写模型的clean方法做校验,避免写入非数值类型的非法数据。


注意事项

不推荐使用FloatField实现:FloatField基于Python的float类型实现,存在二进制精度丢失问题,比如写入0.1时可能被存储为0.1000000000000001,不符合精度要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:36:08