Django - 在FloatField中禁止NaN和无穷大

时间:2017-12-25 21:50:09

标签: python django postgresql

如何在Django中创建一个不允许保存NaN或Infinity值的FloatField(同时仍允许空值) - 也就是说:

class MyModel(models.Model):
    rate = models.FloatField(null=True, nans=False) # ???

我使用Postgres作为后端。如果不存在通用解决方案,可能有Postgres特定的解决方案吗?

2 个答案:

答案 0 :(得分:0)

您可以将其添加为约束,您也可以创建一个类型或域,可以多次使用

CREATE DOMAIN plain_float
        AS float /*NOT NULL*/ check( value <> 'nan'::float AND value > '-inf'::float AND value < '+inf'::float )
        ;

CREATE TABLE dummy
        ( id serial PRIMARY KEY
        , val plain_float
        );

\d dummy

INSERT INTO dummy(val) VALUES ( 0.5);   --Ok
INSERT INTO dummy(val) VALUES ('Nan');  --Fails
INSERT INTO dummy(val) VALUES ('-inf');  --Fails
INSERT INTO dummy(val) VALUES ('+inf');  --Fails

SELECT * FROM dummy;

(我不知道如何将其打包到你的ORM中)

结果:

CREATE DOMAIN
CREATE TABLE
                             Table "tmp.dummy"
 Column |    Type     |                     Modifiers                      
--------+-------------+----------------------------------------------------
 id     | integer     | not null default nextval('dummy_id_seq'::regclass)
 val    | plain_float | 
Indexes:
    "dummy_pkey" PRIMARY KEY, btree (id)

INSERT 0 1
ERROR:  value for domain plain_float violates check constraint "plain_float_check"
ERROR:  value for domain plain_float violates check constraint "plain_float_check"
ERROR:  value for domain plain_float violates check constraint "plain_float_check"
 id | val 
----+-----
  1 | 0.5
(1 row)

答案 1 :(得分:0)

您可以创建自己的自定义字段:

from django.db import models

class HandField(models.FloatField):

    description = "Custom FloatField"

    def check(self, **kwargs):
        errors = super().check(**kwargs)
        errors.extend(self._check_custom_format())
        return errors

def _check_custom_format(self):
    local_errors
    #Here you should check if the format is correct.
    #If something is not right, you should add an error object (from django.core.checks) to local_errors
    return local_errors

错误对象:

checks.Error(
                    'Some error',
                    obj=self,
                    id='Some id',
                )

我还没有尝试过编码,基于IntegerField

https://docs.djangoproject.com/en/2.0/howto/custom-model-fields/ https://docs.djangoproject.com/en/2.0/ref/checks/