mirror of
https://github.com/django/django.git
synced 2025-01-13 11:57:01 +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 of99e5dff737
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…
Reference in New Issue
Block a user