Django-rest-framework: Float yang lebih besar salah lulus validasi DecimalField

Dibuat pada 5 Agu 2015  ·  4Komentar  ·  Sumber: encode/django-rest-framework

Float yang lebih besar tidak gagal validasi DecimalField .

Sebagai contoh:

>>> serializers.DecimalField(max_digits=3, decimal_places=1).run_validation(200000000000.0)
>>> Decimal('2E+11')

Saya berharap ValidationError akan dinaikkan karena angka itu memiliki lebih dari 3 digit. Validasi formulir Django melempar kesalahan yang diharapkan:

>>> 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 dinaikkan jika Anda menjatuhkan nol dari input sampel di atas:

>>> 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.']

Demikian pula, pengecualian juga dimunculkan menggunakan nomor asli tetapi sebagai Decimal dan 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.']

Baris kunci baru-baru ini diubah di https://github.com/tomchristie/Django-rest-framework/pull/2948 tetapi tampaknya tidak benar dan menyimpang dari validasi forms.DecimalField Django yang tampaknya telah disalin kata demi kata:

decimals = exponent * decimal.Decimal(-1) if exponent < 0 else 0

Saya tidak begitu mengerti masalah asli yang dibahas di #2948 jadi saya tidak tahu mengapa barisnya berubah. Saya akan dengan senang hati menangani masalah ini jika saya memahami masalah aslinya.

Di bawah ini adalah tambalan dengan tes yang gagal:

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."])
     )
Bug

Komentar yang paling membantu

Sekarang diselesaikan, dengan logika yang jauh lebih transparan & jelas.

Semua 4 komentar

Terima kasih Ryan.

Sekarang diselesaikan, dengan logika yang jauh lebih transparan & jelas.

@tomchristie @ryankask - Saya melihat ini ditambahkan ke tonggak rilis pada tahun 2015. Saya masih mengalami masalah ini pada versi 3.11.0 . Apakah perbaikannya akhirnya dirilis? Kode di bawah ini:

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 Anda mendapatkan kesalahan validasi yang diharapkan. Grup diskusi adalah tempat terbaik untuk mengambil diskusi ini dan pertanyaan penggunaan lainnya. Terima kasih!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat