mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	[3.2.x] Fixed #32635 -- Fixed system check crash for reverse o2o relations in CheckConstraint.check and UniqueConstraint.condition.
Regression inb7b7df5fbc. Thanks Szymon Zmilczak for the report. Backport ofa77c9a4229from main
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							d6314c4c2e
						
					
				
				
					commit
					700356f93b
				
			| @@ -2076,6 +2076,8 @@ class Model(metaclass=ModelBase): | |||||||
|                 # JOIN must happen at the first lookup. |                 # JOIN must happen at the first lookup. | ||||||
|                 first_lookup = lookups[0] |                 first_lookup = lookups[0] | ||||||
|                 if ( |                 if ( | ||||||
|  |                     hasattr(field, 'get_transform') and | ||||||
|  |                     hasattr(field, 'get_lookup') and | ||||||
|                     field.get_transform(first_lookup) is None and |                     field.get_transform(first_lookup) is None and | ||||||
|                     field.get_lookup(first_lookup) is None |                     field.get_lookup(first_lookup) is None | ||||||
|                 ): |                 ): | ||||||
|   | |||||||
| @@ -22,3 +22,7 @@ Bugfixes | |||||||
|  |  | ||||||
| * Restored, following a regression in Django 3.2, displaying an exception | * Restored, following a regression in Django 3.2, displaying an exception | ||||||
|   message on the technical 404 debug page (:ticket:`32637`). |   message on the technical 404 debug page (:ticket:`32637`). | ||||||
|  |  | ||||||
|  | * Fixed a bug in Django 3.2 where a system check would crash on a reverse | ||||||
|  |   one-to-one relationships in ``CheckConstraint.check`` or | ||||||
|  |   ``UniqueConstraint.condition`` (:ticket:`32635`). | ||||||
|   | |||||||
| @@ -1694,6 +1694,27 @@ class ConstraintsTests(TestCase): | |||||||
|             ), |             ), | ||||||
|         ]) |         ]) | ||||||
|  |  | ||||||
|  |     @skipUnlessDBFeature('supports_table_check_constraints') | ||||||
|  |     def test_check_constraint_pointing_to_reverse_o2o(self): | ||||||
|  |         class Model(models.Model): | ||||||
|  |             parent = models.OneToOneField('self', models.CASCADE) | ||||||
|  |  | ||||||
|  |             class Meta: | ||||||
|  |                 constraints = [ | ||||||
|  |                     models.CheckConstraint( | ||||||
|  |                         name='name', | ||||||
|  |                         check=models.Q(model__isnull=True), | ||||||
|  |                     ), | ||||||
|  |                 ] | ||||||
|  |  | ||||||
|  |         self.assertEqual(Model.check(databases=self.databases), [ | ||||||
|  |             Error( | ||||||
|  |                 "'constraints' refers to the nonexistent field 'model'.", | ||||||
|  |                 obj=Model, | ||||||
|  |                 id='models.E012', | ||||||
|  |             ), | ||||||
|  |         ]) | ||||||
|  |  | ||||||
|     @skipUnlessDBFeature('supports_table_check_constraints') |     @skipUnlessDBFeature('supports_table_check_constraints') | ||||||
|     def test_check_constraint_pointing_to_m2m_field(self): |     def test_check_constraint_pointing_to_m2m_field(self): | ||||||
|         class Model(models.Model): |         class Model(models.Model): | ||||||
| @@ -1933,6 +1954,28 @@ class ConstraintsTests(TestCase): | |||||||
|             ) |             ) | ||||||
|         ] if connection.features.supports_partial_indexes else []) |         ] if connection.features.supports_partial_indexes else []) | ||||||
|  |  | ||||||
|  |     def test_unique_constraint_pointing_to_reverse_o2o(self): | ||||||
|  |         class Model(models.Model): | ||||||
|  |             parent = models.OneToOneField('self', models.CASCADE) | ||||||
|  |  | ||||||
|  |             class Meta: | ||||||
|  |                 required_db_features = {'supports_partial_indexes'} | ||||||
|  |                 constraints = [ | ||||||
|  |                     models.UniqueConstraint( | ||||||
|  |                         fields=['parent'], | ||||||
|  |                         name='name', | ||||||
|  |                         condition=models.Q(model__isnull=True), | ||||||
|  |                     ), | ||||||
|  |                 ] | ||||||
|  |  | ||||||
|  |         self.assertEqual(Model.check(databases=self.databases), [ | ||||||
|  |             Error( | ||||||
|  |                 "'constraints' refers to the nonexistent field 'model'.", | ||||||
|  |                 obj=Model, | ||||||
|  |                 id='models.E012', | ||||||
|  |             ), | ||||||
|  |         ] if connection.features.supports_partial_indexes else []) | ||||||
|  |  | ||||||
|     def test_deferrable_unique_constraint(self): |     def test_deferrable_unique_constraint(self): | ||||||
|         class Model(models.Model): |         class Model(models.Model): | ||||||
|             age = models.IntegerField() |             age = models.IntegerField() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user