PostgreSQL NUMERIC数据类型的Django模型字段

rnmwe5a2  于 2023-10-21  发布在  Go
关注(0)|答案(2)|浏览(128)

我正在使用Django创建一个应用程序(使用PostgreSQL),它需要一个列数字(15,6),但我没有找到一个方法来做到这一点。

niknxzdl

niknxzdl1#

PostgreSQL docs:

decimal和numeric类型等价。这两种类型都是SQL标准的一部分。

所以你可以使用Django的DecimalField

class MyModel(models.Model):
    my_field = models.DecimalField(max_digits=15, decimal_places=6)

一些文档:

  • http://www.postgresql.org/docs/current/interactive/datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL
  • https://docs.djangoproject.com/en/1.8/ref/forms/fields/#decimalfield
guz6ccqo

guz6ccqo2#

希望添加到答案,但我没有足够的声誉评论。这是关于如何为PostgreSQL NUMERIC类型添加Django模型字段,而无需指定精度和小数位数。
正如上面的答案所说,我们在postgres中有NUMERIC(precision, scale)。在models.DecimalField(max_digits=15, decimal_places=6)中,max_digitsMap到precisiondecimal_placesMap到scale
在postgres文档中,它说“没有任何精度或小数位数的NUMERIC创建了一个“无约束的数字”列,其中可以存储任何长度的数值,直到实现限制。这种列不会将输入值强制为任何特定的小数位数,而具有声明小数位数的数值列将强制输入值为该小数位数。
这意味着如果你有NUMERIC(15,6),如果你输入1.2,插入到postgres中的数据将被强制转换为1.200000。但是如果你有NUMERIC,那么插入的数据将保持原样,即。1.2
我发现this great article在谈论如何在models.py中创建一个新的ArbitraryDecimalField,它覆盖了在Django models.DecimalField中声明max_digitsdecimal_places的要求,这样我们就可以指定postgres NUMERIC数据类型,而无需声明精度和小数位数。当我使用Model.objects.create()进行测试以直接在数据库中创建和保存对象时,这是可行的。
如果我想使用Django REST框架编写的API通过POST请求创建对象,我会得到与rest_framework.serializers相关的错误:

TypeError: __init__() missing 2 required positional arguments: 'max_digits' and 'decimal_places'

挖掘django rest framework源码serializers.pyfields.py,为了防止Django项目www.example.com中的错误serializers.py,我们需要在serializers.DecimalField中设置max_digitsdecimal_places为None。这是一个样品。
models.py(基于this great article

from django.db import models

class ArbitraryDecimalField(models.DecimalField):
    def _check_decimal_places(self):
        return []
    def _check_max_digits(self):
        return []

    def _check_decimal_places_and_max_digits(self):
        return []

    def db_type(self, connection):
        # pg or bust
        assert connection.settings_dict["ENGINE"] == "django.db.backends.postgresql"
        return "numeric"

class SampleModel(models.Model):
    my_num = ArbitraryDecimalField()

serializers.py

from rest_framework import serializers
from models import SampleModel

class SampleSerializer(serializers.ModelSerializer):
    my_num = serializers.DecimalField(max_digits=None, decimal_places=None)
    class Meta:
        model = SampleModel
        fields = ['my_num']

相关问题