Les plus gros flottants n'échouent pas DecimalField
validation
Par exemple:
>>> serializers.DecimalField(max_digits=3, decimal_places=1).run_validation(200000000000.0)
>>> Decimal('2E+11')
Je m'attendrais à ce qu'un ValidationError
soit collecté puisque ce nombre a plus de 3 chiffres. La validation de formulaire de Django renvoie l'erreur attendue :
>>> forms.DecimalField(max_digits=3, decimal_places=1).clean(200000000000.0)
ValidationError: [u'Ensure that there are no more than 3 digits in total.']
ValidationError
est généré si vous supprimez un zéro de l'exemple d'entrée ci-dessus :
>>> serializers.DecimalField(max_digits=3, decimal_places=1).run_validation(20000000000.0)
ValidationError: [u'Ensure that there are no more than 3 digits in total.']
De même, l'exception est également levée en utilisant le nombre d'origine mais sous la forme d'un Decimal
et d'un int :
>>> serializers.DecimalField(max_digits=3, decimal_places=1).run_validation(200000000000)
ValidationError: [u'Ensure that there are no more than 3 digits in total.']
>>> serializers.DecimalField(max_digits=3, decimal_places=1).run_validation(Decimal('200000000000.0'))
ValidationError: [u'Ensure that there are no more than 3 digits in total.']
Une ligne de clé a récemment changé dans https://github.com/tomchristie/django-rest-framework/pull/2948 mais elle ne semble pas correcte et s'écarte de la validation forms.DecimalField
de Django qui semble autrement avoir été copiée textuellement:
decimals = exponent * decimal.Decimal(-1) if exponent < 0 else 0
Je ne comprends pas vraiment le problème d'origine abordé dans #2948, donc je ne sais pas pourquoi la ligne a changé. Je suis plus qu'heureux de travailler sur le problème si je comprends le problème d'origine.
Vous trouverez ci-dessous un correctif avec un test raté :
diff --git a/tests/test_fields.py b/tests/test_fields.py
index 0427873..cf41a5b 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -773,6 +773,7 @@ class TestDecimalField(FieldValues):
(Decimal('Nan'), ["A valid number is required."]),
(Decimal('Inf'), ["A valid number is required."]),
('12.345', ["Ensure that there are no more than 3 digits in total."]),
+ (200000000000.0, ["Ensure that there are no more than 3 digits in total."]),
('0.01', ["Ensure that there are no more than 1 decimal places."]),
(123, ["Ensure that there are no more than 2 digits before the decimal point."])
)
Merci Ryan.
Maintenant résolu, avec une logique beaucoup plus transparente et évidente.
@tomchristie @ryankask - Je vois que cela a été ajouté à un jalon de publication en 2015. Je rencontre toujours ce problème sur la version 3.11.0
. Le correctif a-t-il fini par être publié? Code ci-dessous :
class RecommendationSerializer(serializers.Serializer):
total_owed = serializers.DecimalField(decimal_places=2, max_digits=8, min_value='1.00',
rounding=ROUND_DOWN)
term_length = serializers.IntegerField(min_value=1)
class Meta:
fields = ['total_owed', 'term_length']
serializer = RecommendationSerializer(data={'total_owed': '12.333333333333333', 'term_length': 6})
serializer.is_valid(raise_exception=True)
>>> {"total_owed": ["Ensure that there are no more than 8 digits in total."]}
@Audace vous obtenez l'erreur de validation attendue. Le groupe de discussion est le meilleur endroit pour prendre cette discussion et d'autres questions d'utilisation. Merci!
Commentaire le plus utile
Maintenant résolu, avec une logique beaucoup plus transparente et évidente.