Django-rest-framework: ํฐ ์ˆ˜๋ ˆ๊ฐ€ DecimalField ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ž˜๋ชป ํ†ต๊ณผํ•จ

์— ๋งŒ๋“  2015๋…„ 08์›” 05์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: encode/django-rest-framework

๋” ํฐ ์ˆ˜๋ ˆ๋Š” DecimalField ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ์‹คํŒจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด:

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

๊ทธ ์ˆซ์ž๊ฐ€ 3์ž๋ฆฌ ์ด์ƒ์ด๋ฏ€๋กœ ValidationError ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค. Django์˜ ์–‘์‹ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์—์„œ ์˜ˆ์ƒ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

>>> forms.DecimalField(max_digits=3, decimal_places=1).clean(200000000000.0)
ValidationError: [u'Ensure that there are no more than 3 digits in total.']

์œ„์˜ ์ƒ˜ํ”Œ ์ž…๋ ฅ์—์„œ 0์„ ์‚ญ์ œํ•˜๋ฉด ValidationError ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

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

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์›๋ž˜ ๋ฒˆํ˜ธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Decimal ๋ฐ 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.']

์ตœ๊ทผ์— https://github.com/tomchristie/django-rest-framework/pull/2948 ์—์„œ ํ•ต์‹ฌ ๋ผ์ธ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์ง€๋งŒ ์ •ํ™•ํ•˜์ง€ ์•Š๊ณ  Django์˜ forms.DecimalField ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์—์„œ ๋ฒ—์–ด๋‚˜ ๋ณต์‚ฌ๋œ ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. ๊ทธ๋Œ€๋กœ:

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

#2948์—์„œ ์–ธ๊ธ‰๋œ ์›๋ž˜ ๋ฌธ์ œ๋ฅผ ์ •๋ง ์ดํ•ดํ•˜์ง€ ๋ชปํ•ด์„œ ์ค„์ด ์™œ ๋ฐ”๋€Œ์—ˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์›๋ž˜ ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ๊ธฐ๊บผ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ํ…Œ์ŠคํŠธ์— ์‹คํŒจํ•œ ํŒจ์น˜์ž…๋‹ˆ๋‹ค.

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

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด์ œ ํ›จ์”ฌ ๋” ํˆฌ๋ช…ํ•˜๊ณ  ๋ถ„๋ช…ํ•œ ๋…ผ๋ฆฌ๋กœ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  4 ๋Œ“๊ธ€

๊ณ ๋งˆ์›Œ ๋ผ์ด์–ธ.

์ด์ œ ํ›จ์”ฌ ๋” ํˆฌ๋ช…ํ•˜๊ณ  ๋ถ„๋ช…ํ•œ ๋…ผ๋ฆฌ๋กœ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@tomchristie @ryankask - 2015๋…„์— ๋ฆด๋ฆฌ์Šค ์ด์ •ํ‘œ์— ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 3.11.0 ๋ฒ„์ „์—์„œ ์—ฌ์ „ํžˆ ์ด ๋ฌธ์ œ๋ฅผ ๊ฒช๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆ˜์ • ์‚ฌํ•ญ์ด ๊ฒฐ๊ตญ ๋ฆด๋ฆฌ์Šค ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ์•„๋ž˜ ์ฝ”๋“œ:

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 ์˜ˆ์ƒ๋˜๋Š” ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ† ๋ก  ๊ทธ๋ฃน ์€ ์ด ํ† ๋ก  ๋ฐ ๊ธฐํƒ€ ์‚ฌ์šฉ ์งˆ๋ฌธ์„ ํ•˜๊ธฐ์— ๊ฐ€์žฅ ์ข‹์€ ์žฅ์†Œ์ž…๋‹ˆ๋‹ค. ๊ฐ์‚ฌ!

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰