You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django-money的MoneyField中能否为Min/MaxMoneyValidator设置带小数数值?

关于Django-money中MinMoneyValidator/MaxMoneyValidator传入小数的问题

问题场景

使用Django-money的MoneyField时,为MinMoneyValidator传入0.00、MaxMoneyValidator传入999.99,代码如下:

# "models.py"

from django.db import models
from djmoney.models.fields import MoneyField
from djmoney.models.validators import MinMoneyValidator, MaxMoneyValidator 

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = MoneyField(
        max_digits=5, decimal_places=2, default=0, default_currency='USD',
        validators=[
            MinMoneyValidator(0.00), MaxMoneyValidator(999.99),
        ]
    )

添加商品时触发错误:

TypeError: 'float' object is not subscriptable

改为传入整数0和999后错误消失,但Django原生DecimalField中给MinValueValidator/MaxValueValidator传入0.00、999.99完全正常:

# "models.py"

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator 

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.DecimalField(
        max_digits=5, decimal_places=2, default=0,
        validators=[
            MinValueValidator(0.00), MaxValueValidator(999.99)
        ],
    )

错误原因

Django-money的MinMoneyValidator/MaxMoneyValidator内部逻辑会尝试对传入的验证值做类序列的下标操作(比如提取金额部分),但直接传入float类型的数值时,float对象不支持下标访问,因此抛出TypeError。

而Django原生的数值验证器是直接处理数值类型,对float有兼容逻辑,所以不会触发错误。

正确设置带小数的验证值

并非不能设置带小数的验证值,而是需要传入Decimal类型或者Django-money的Money对象,而非float:

方法1:使用Decimal类型

# "models.py"

from django.db import models
from decimal import Decimal
from djmoney.models.fields import MoneyField
from djmoney.models.validators import MinMoneyValidator, MaxMoneyValidator 

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = MoneyField(
        max_digits=5, decimal_places=2, default=0, default_currency='USD',
        validators=[
            MinMoneyValidator(Decimal('0.00')),
            MaxMoneyValidator(Decimal('999.99')),
        ]
    )

方法2:使用Money对象

# "models.py"

from django.db import models
from djmoney.models.fields import MoneyField
from djmoney.money import Money
from djmoney.models.validators import MinMoneyValidator, MaxMoneyValidator 

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = MoneyField(
        max_digits=5, decimal_places=2, default=0, default_currency='USD',
        validators=[
            MinMoneyValidator(Money(0.00, 'USD')),
            MaxMoneyValidator(Money(999.99, 'USD')),
        ]
    )

内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 18:05:29