Skip to content

Commit ea65f01

Browse files
committed
For now, don't cache related values
When doing refresh_from_db(), Django only looks at obj._meta.concrete_fields and obj._meta.related_objects when assessing which caches to bust. In cases where Relationship provides a single object descriptor, we currently thread the needle between these two sets - Django considers us neither a related object nor a concrete field - and so the field cache is never cleared. For now, solve this by never allowing related objects to be cached.
1 parent 80d3130 commit ea65f01

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

relativity/fields.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,14 @@ def __get__(self, instance, cls=None):
289289
return None
290290
else:
291291
raise
292+
finally:
293+
# TODO: figure out how to persuade Django to treat us a normal related_object
294+
if django.VERSION < (2,):
295+
if hasattr(instance, self.cache_name):
296+
delattr(instance, self.cache_name)
297+
else:
298+
if self.related.is_cached(instance):
299+
self.related.delete_cached_value(instance)
292300

293301

294302
# noinspection PyProtectedMember

tests/tests.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,16 @@ def test_m2m(self):
345345

346346
def test_single_reverse(self):
347347
node_1 = LinkedNode.objects.create(
348-
name="first node", prev_id=None,
348+
name="first node",
349+
prev_id=None,
349350
)
350351
node_2 = LinkedNode.objects.create(
351-
name="next node", prev_id=node_1.id,
352+
name="next node",
353+
prev_id=node_1.id,
352354
)
353355
node_3 = LinkedNode.objects.create(
354-
name="last node", prev_id=node_2.id,
356+
name="last node",
357+
prev_id=node_2.id,
355358
)
356359
self.assertEqual(node_3.prev, node_2)
357360
self.assertEqual(node_1.next, node_2)
@@ -371,3 +374,11 @@ def test_not_nullable(self):
371374
def test_complex_expression(self):
372375
ug = UserGenerator.objects.create()
373376
self.assertEqual(ug.user, User.objects.get(username="generated_for_%d" % ug.id))
377+
378+
def test_descriptor_not_cached(self):
379+
item = CartItem.objects.first()
380+
self.assertIsNotNone(item.product)
381+
382+
item.product.delete()
383+
with self.assertRaises(Product.DoesNotExist):
384+
item.product

0 commit comments

Comments
 (0)