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

问题描述 投票:0回答:2

我正在使用 Django 创建一个需要列 numeric(15,6) 的应用程序(使用 PostgreSQL),但我没有找到执行此操作的方法。

python django postgresql django-models numeric
2个回答
13
投票

来自 PostgreSQL 文档:

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

所以你可以使用Django的

DecimalField

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

一些文档:


0
投票

希望补充答案,但我没有足够的声誉来发表评论。这是关于如何为 PostgreSQL NUMERIC 类型添加 Django 模型字段,而不指定精度和小数位数。

正如上面的答案所说,我们在 postgres 中有

NUMERIC(precision, scale)
。在
models.DecimalField(max_digits=15, decimal_places=6)
中,
max_digits
映射到
precision
decimal_places
映射到
scale

在 postgres 文档中,它说“没有任何精度或小数位数的 NUMERIC 创建一个“不受约束的数字”列,其中可以存储任何长度的数值,直至实现限制。这种类型的列不会将输入值强制为任何特定比例,而具有声明比例的数字列会将输入值强制为该比例。'

这意味着如果你有

NUMERIC(15,6)
,如果你输入
1.2
,插入postgres的数据将被强制为
1.200000
。但如果你有
NUMERIC
,那么插入的数据将保持原样,即
1.2

我发现这篇很棒的文章讨论了如何在

ArbitraryDecimalField
中创建一个新的
models.py
,它覆盖了在Django
max_digits
中声明
decimal_places
models.DecimalField
的要求,以便我们可以指定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框架源代码serializers.pyfields.py,为了防止Django项目serializers.py中出现错误,我们需要将

max_digits
中的
decimal_places
serializers.DecimalField
设置为没有任何。这是一个示例。

models.py(基于这篇很棒的文章

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()

序列化器.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']
© www.soinside.com 2019 - 2024. All rights reserved.