mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[2.0.x] Fixed #28562 -- Fixed DecimalValidator handling of positive exponent scientific notation.
Backport of e8c4596329 from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							5b38d7e973
						
					
				
				
					commit
					7c6590af5f
				
			| @@ -414,15 +414,21 @@ class DecimalValidator: | ||||
|  | ||||
|     def __call__(self, value): | ||||
|         digit_tuple, exponent = value.as_tuple()[1:] | ||||
|         decimals = abs(exponent) | ||||
|         # digit_tuple doesn't include any leading zeros. | ||||
|         digits = len(digit_tuple) | ||||
|         if decimals > digits: | ||||
|             # We have leading zeros up to or past the decimal point. Count | ||||
|             # everything past the decimal point as a digit. We do not count | ||||
|             # 0 before the decimal point as a digit since that would mean | ||||
|             # we would not allow max_digits = decimal_places. | ||||
|             digits = decimals | ||||
|         if exponent >= 0: | ||||
|             # A positive exponent adds that many trailing zeros. | ||||
|             digits = len(digit_tuple) + exponent | ||||
|             decimals = 0 | ||||
|         else: | ||||
|             # If the absolute value of the negative exponent is larger than the | ||||
|             # number of digits, then it's the same as the number of digits, | ||||
|             # because it'll consume all of the digits in digit_tuple and then | ||||
|             # add abs(exponent) - len(digit_tuple) leading zeros after the | ||||
|             # decimal point. | ||||
|             if abs(exponent) > len(digit_tuple): | ||||
|                 digits = decimals = abs(exponent) | ||||
|             else: | ||||
|                 digits = len(digit_tuple) | ||||
|                 decimals = abs(exponent) | ||||
|         whole_digits = digits - decimals | ||||
|  | ||||
|         if self.max_digits is not None and digits > self.max_digits: | ||||
|   | ||||
| @@ -119,11 +119,12 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase): | ||||
|             f.clean('1.1') | ||||
|  | ||||
|     def test_decimalfield_scientific(self): | ||||
|         f = DecimalField(max_digits=2, decimal_places=2) | ||||
|         self.assertEqual(f.clean('1E+2'), decimal.Decimal('1E+2')) | ||||
|         self.assertEqual(f.clean('1e+2'), decimal.Decimal('1E+2')) | ||||
|         f = DecimalField(max_digits=4, decimal_places=2) | ||||
|         with self.assertRaisesMessage(ValidationError, "Ensure that there are no more"): | ||||
|             f.clean('0.546e+2') | ||||
|             f.clean('1E+2') | ||||
|         self.assertEqual(f.clean('1E+1'), decimal.Decimal('10')) | ||||
|         self.assertEqual(f.clean('1E-1'), decimal.Decimal('0.1')) | ||||
|         self.assertEqual(f.clean('0.546e+2'), decimal.Decimal('54.6')) | ||||
|  | ||||
|     def test_decimalfield_widget_attrs(self): | ||||
|         f = DecimalField(max_digits=6, decimal_places=2) | ||||
|   | ||||
| @@ -265,6 +265,7 @@ TEST_DATA = [ | ||||
|     (DecimalValidator(max_digits=3, decimal_places=1), Decimal('999'), ValidationError), | ||||
|     (DecimalValidator(max_digits=4, decimal_places=1), Decimal('999'), None), | ||||
|     (DecimalValidator(max_digits=20, decimal_places=2), Decimal('742403889818000000'), None), | ||||
|     (DecimalValidator(20, 2), Decimal('7.42403889818E+17'), None), | ||||
|     (DecimalValidator(max_digits=20, decimal_places=2), Decimal('7424742403889818000000'), ValidationError), | ||||
|     (DecimalValidator(max_digits=5, decimal_places=2), Decimal('7304E-1'), None), | ||||
|     (DecimalValidator(max_digits=5, decimal_places=2), Decimal('7304E-3'), ValidationError), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user