我想在Place模型中保存纬度和经度。 我尝试了两个字段,floatfield和decimalfield。
class Place1(models.Model):
latitude = models.FloatField()
longitude = models.FloatField()
class Place2(models.Model):
latitude = models.DecimalField(max_digits=18, decimal_places=16)
longitude = models.DecimalField(max_digits=19, decimal_places=16)
两个字段都在以下值上运作良好。
10.1
10.12
10.123
10.1234
...
10.1234567890123
但是,在第16个数字(不是'十六个小数位')之后,保存时它会无意中舍入。
place1 = Place1.objects.create(
latitude=10.123456789012345,
longitude=100.123456789012345
)
>>place1.latitude
10.123456789012345 # works well
>>place1.longitude
100.123456789012345 # works well
# Unintentionally rounded when I get object from db.
>>Place.objects.last().latitude
10.12345678901235 # unintentionally rounded
>>Place.objects.last().longitude
100.1234567890123 # unintentionally rounded
place2 = Place2.objects.create(
latitude=Decimal('10.123456789012345'),
longitude=Decimal('100.123456789012345')
)
>>place2.latitude
Decimal('10.1234567890123450') # works well
>>place2.longitude
Decimal('100.1234567890123450') # works well
# Unintentionally rounded when I get object from db.
>>Place.objects.last().latitude
Decimal('10.1234567890123500') # unintentionally rounded
>>Place.objects.last().longitude
Decimal('100.1234567890123000') # unintentionally rounded
我无法找到关于此无意识轮次的任何解释。在django文件中。请帮忙。感谢。
答案 0 :(得分:1)
你不能在django docs中找到'无意的舍入',因为django不是这里的罪魁祸首。
当您的列数据类型为Float时,它会执行舍入的MYSQL。
为了获得最大的可移植性,需要存储近似数值数据值的代码应使用 FLOAT 或 DOUBLE PRECISION ,不能指定精度或位数。
由于浮点值是近似值而未存储为精确值,因此尝试在比较中将它们视为精确值可能会导致问题。它们还受平台或实现依赖性的影响。
但是对于值的准确性,您应该使用 DecimalField 。
你说你使用过 DecimalField ,但这些数字仍在四舍五入。这可能会发生,因为您的表格列仍然是 Float 类型,而不是十进制。
将表格列类型更改为十进制,您可以看到更改。
示例SQL语法ALTER TABLE your_table MODIFY latitude decimal(m,n);
,OR
如果您使用的是MYSQL Workbench或任何UI界面,请直接从列信息标签中更改它(它们有一个)
DECIMAL和NUMERIC类型存储精确的数值数据值。在保持精确精度
非常重要时使用这些类型在DECIMAL列声明中,可以(通常是)指定精度和比例;例如:纬度DECIMAL(m,n)
精度(m)表示为值存储的有效位数,而(n)表示可以存储的位数小数点。
在这里为您的田地纬度和经度所需的精确比例提供帮助