mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	[4.2.x] Fixed #34570 -- Silenced noop deferral of many-to-many and GFK.
While deferring many-to-many and GFK has no effect, the previous implementation of QuerySet.defer() ignore them instead of crashing. Regression inb3db6c8dcb. Thanks Paco Martínez for the report. Backport of99e5dff737from main
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							9c301814b0
						
					
				
				
					commit
					201d29b371
				
			| @@ -725,7 +725,15 @@ class Query(BaseExpression): | ||||
|                 field_select_mask = select_mask.setdefault((field_name, relation), {}) | ||||
|                 field = relation.field | ||||
|             else: | ||||
|                 field = opts.get_field(field_name).field | ||||
|                 reverse_rel = opts.get_field(field_name) | ||||
|                 # While virtual fields such as many-to-many and generic foreign | ||||
|                 # keys cannot be effectively deferred we've historically | ||||
|                 # allowed them to be passed to QuerySet.defer(). Ignore such | ||||
|                 # field references until a layer of validation at mask | ||||
|                 # alteration time will be implemented eventually. | ||||
|                 if not hasattr(reverse_rel, "field"): | ||||
|                     continue | ||||
|                 field = reverse_rel.field | ||||
|                 field_select_mask = select_mask.setdefault(field, {}) | ||||
|             related_model = field.model._meta.concrete_model | ||||
|             self._get_defer_select_mask( | ||||
|   | ||||
| @@ -15,3 +15,7 @@ Bugfixes | ||||
|  | ||||
| * Restored, following a regression in Django 4.2, ``get_prep_value()`` call in | ||||
|   ``JSONField`` subclasses (:ticket:`34539`). | ||||
|  | ||||
| * Fixed a regression in Django 4.2 that caused a crash of ``QuerySet.defer()`` | ||||
|   when passing a ``ManyToManyField`` or ``GenericForeignKey`` reference. While | ||||
|   doing so is a no-op, it was allowed in older version (:ticket:`34570`). | ||||
|   | ||||
| @@ -296,6 +296,12 @@ class DeferRegressionTest(TestCase): | ||||
|         with self.assertNumQueries(1): | ||||
|             self.assertEqual(leaf.second_child.value, 64) | ||||
|  | ||||
|     def test_defer_many_to_many_ignored(self): | ||||
|         location = Location.objects.create() | ||||
|         request = Request.objects.create(location=location) | ||||
|         with self.assertNumQueries(1): | ||||
|             self.assertEqual(Request.objects.defer("items").get(), request) | ||||
|  | ||||
|  | ||||
| class DeferDeletionSignalsTests(TestCase): | ||||
|     senders = [Item, Proxy] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user