mirror of
https://github.com/django/django.git
synced 2025-02-28 19:44:35 +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 in b3db6c8dcb5145f7d45eff517bcd96460475c879. Thanks Paco Martínez for the report. Backport of 99e5dff737cd20b12d060e4794e097063b61ec40 from main
This commit is contained in:
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]
|
||||
|
Loading…
x
Reference in New Issue
Block a user