1
0
mirror of https://github.com/django/django.git synced 2025-11-07 07:15:35 +00:00

Refs #28586 -- Made fetch modes pickle as singletons.

This change ensures that we don’t create new instances of fetch modes
when pickling and unpickling, saving memory and preserving their singleton
nature.
This commit is contained in:
Adam Johnson
2025-09-05 11:04:27 +01:00
committed by Jacob Walls
parent e097e8a12f
commit a321d961b0
2 changed files with 32 additions and 0 deletions

View File

@@ -16,6 +16,9 @@ class FetchOne(FetchMode):
def fetch(self, fetcher, instance):
fetcher.fetch_one(instance)
def __reduce__(self):
return "FETCH_ONE"
FETCH_ONE = FetchOne()
@@ -36,6 +39,9 @@ class FetchPeers(FetchMode):
else:
fetcher.fetch_one(instance)
def __reduce__(self):
return "FETCH_PEERS"
FETCH_PEERS = FetchPeers()
@@ -48,5 +54,8 @@ class Raise(FetchMode):
field_name = fetcher.field.name
raise FieldFetchBlocked(f"Fetching of {klass}.{field_name} blocked.") from None
def __reduce__(self):
return "RAISE"
RAISE = Raise()

View File

@@ -351,6 +351,29 @@ class PickleabilityTestCase(TestCase):
event.edition_set.create()
self.assert_pickles(event.edition_set.order_by("event"))
def test_fetch_mode_fetch_one(self):
restored = pickle.loads(pickle.dumps(self.happening))
self.assertIs(restored._state.fetch_mode, models.FETCH_ONE)
def test_fetch_mode_fetch_peers(self):
Happening.objects.create()
objs = list(Happening.objects.fetch_mode(models.FETCH_PEERS))
self.assertEqual(objs[0]._state.fetch_mode, models.FETCH_PEERS)
self.assertEqual(len(objs[0]._state.peers), 2)
restored = pickle.loads(pickle.dumps(objs))
self.assertIs(restored[0]._state.fetch_mode, models.FETCH_PEERS)
# Peers not restored because weak references are not picklable.
self.assertEqual(restored[0]._state.peers, ())
def test_fetch_mode_raise(self):
objs = list(Happening.objects.fetch_mode(models.RAISE))
self.assertEqual(objs[0]._state.fetch_mode, models.RAISE)
restored = pickle.loads(pickle.dumps(objs))
self.assertIs(restored[0]._state.fetch_mode, models.RAISE)
class InLookupTests(TestCase):
@classmethod