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
相关产品推荐
相关产品推荐

