mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +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
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