mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[2.2.x] Fixed #30328 -- Fixed crash of IntegerField.validators when limit_value in a custom validator is callable.
Backport of a14c0fda15 from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							bb54a2daee
						
					
				
				
					commit
					95811c3de9
				
			
							
								
								
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -757,6 +757,7 @@ answer newbie questions, and generally made Django that much better: | ||||
|     schwank@gmail.com | ||||
|     Scot Hacker <shacker@birdhouse.org> | ||||
|     Scott Barr <scott@divisionbyzero.com.au> | ||||
|     Scott Fitsimones <scott@airgara.ge> | ||||
|     Scott Pashley <github@scottpashley.co.uk> | ||||
|     scott@staplefish.com | ||||
|     Sean Brant | ||||
|   | ||||
| @@ -1790,13 +1790,25 @@ class IntegerField(Field): | ||||
|         validators_ = super().validators | ||||
|         internal_type = self.get_internal_type() | ||||
|         min_value, max_value = connection.ops.integer_field_range(internal_type) | ||||
|         if (min_value is not None and not | ||||
|             any(isinstance(validator, validators.MinValueValidator) and | ||||
|                 validator.limit_value >= min_value for validator in validators_)): | ||||
|         if min_value is not None and not any( | ||||
|             ( | ||||
|                 isinstance(validator, validators.MinValueValidator) and ( | ||||
|                     validator.limit_value() | ||||
|                     if callable(validator.limit_value) | ||||
|                     else validator.limit_value | ||||
|                 ) >= min_value | ||||
|             ) for validator in validators_ | ||||
|         ): | ||||
|             validators_.append(validators.MinValueValidator(min_value)) | ||||
|         if (max_value is not None and not | ||||
|             any(isinstance(validator, validators.MaxValueValidator) and | ||||
|                 validator.limit_value <= max_value for validator in validators_)): | ||||
|         if max_value is not None and not any( | ||||
|             ( | ||||
|                 isinstance(validator, validators.MaxValueValidator) and ( | ||||
|                     validator.limit_value() | ||||
|                     if callable(validator.limit_value) | ||||
|                     else validator.limit_value | ||||
|                 ) <= max_value | ||||
|             ) for validator in validators_ | ||||
|         ): | ||||
|             validators_.append(validators.MaxValueValidator(max_value)) | ||||
|         return validators_ | ||||
|  | ||||
|   | ||||
| @@ -38,3 +38,7 @@ Bugfixes | ||||
|   :class:`~django.core.paginator.Paginator` crashed when ``object_list`` was | ||||
|   a queryset ordered or aggregated over a nested ``JSONField`` key transform | ||||
|   (:ticket:`30335`). | ||||
|  | ||||
| * Fixed a regression in Django 2.2 where ``IntegerField`` validation of | ||||
|   database limits crashes if ``limit_value`` attribute in a custom validator is | ||||
|   callable (:ticket:`30328`). | ||||
|   | ||||
| @@ -98,26 +98,30 @@ class IntegerFieldTests(TestCase): | ||||
|         """ | ||||
|         min_backend_value, max_backend_value = self.backend_range | ||||
|  | ||||
|         for callable_limit in (True, False): | ||||
|             with self.subTest(callable_limit=callable_limit): | ||||
|                 if min_backend_value is not None: | ||||
|                     min_custom_value = min_backend_value + 1 | ||||
|                     limit_value = (lambda: min_custom_value) if callable_limit else min_custom_value | ||||
|                     ranged_value_field = self.model._meta.get_field('value').__class__( | ||||
|                 validators=[validators.MinValueValidator(min_custom_value)] | ||||
|                         validators=[validators.MinValueValidator(limit_value)] | ||||
|                     ) | ||||
|                     field_range_message = validators.MinValueValidator.message % { | ||||
|                         'limit_value': min_custom_value, | ||||
|                     } | ||||
|             with self.assertRaisesMessage(ValidationError, "[%r]" % field_range_message): | ||||
|                     with self.assertRaisesMessage(ValidationError, '[%r]' % field_range_message): | ||||
|                         ranged_value_field.run_validators(min_backend_value - 1) | ||||
|  | ||||
|                 if max_backend_value is not None: | ||||
|                     max_custom_value = max_backend_value - 1 | ||||
|                     limit_value = (lambda: max_custom_value) if callable_limit else max_custom_value | ||||
|                     ranged_value_field = self.model._meta.get_field('value').__class__( | ||||
|                 validators=[validators.MaxValueValidator(max_custom_value)] | ||||
|                         validators=[validators.MaxValueValidator(limit_value)] | ||||
|                     ) | ||||
|                     field_range_message = validators.MaxValueValidator.message % { | ||||
|                         'limit_value': max_custom_value, | ||||
|                     } | ||||
|             with self.assertRaisesMessage(ValidationError, "[%r]" % field_range_message): | ||||
|                     with self.assertRaisesMessage(ValidationError, '[%r]' % field_range_message): | ||||
|                         ranged_value_field.run_validators(max_backend_value + 1) | ||||
|  | ||||
|     def test_types(self): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user