From b9838c65ec2fee36c1fd0d46494ba44da27a9b34 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 3 May 2024 17:18:06 +0100 Subject: Fixed #35405 -- Converted get_cache_name into a cached property in FieldCacheMixin. FieldCacheMixin is used by related fields to track their cached values. This work migrates get_cache_name() to be a cached property to optimize performance by reducing unnecessary function calls when working with related fields, given that its value remains constant. Co-authored-by: Simon Charette Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> --- tests/model_fields/test_mixins.py | 75 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 tests/model_fields/test_mixins.py (limited to 'tests') diff --git a/tests/model_fields/test_mixins.py b/tests/model_fields/test_mixins.py new file mode 100644 index 0000000000..5ccfac4d78 --- /dev/null +++ b/tests/model_fields/test_mixins.py @@ -0,0 +1,75 @@ +from django.db.models.fields.mixins import FieldCacheMixin +from django.test import SimpleTestCase +from django.utils.deprecation import RemovedInDjango60Warning +from django.utils.functional import cached_property + +from .models import Foo + + +# RemovedInDjango60Warning. +class ExampleOld(FieldCacheMixin): + def get_cache_name(self): + return "example" + + +class Example(FieldCacheMixin): + @cached_property + def cache_name(self): + return "example" + + +class FieldCacheMixinTests(SimpleTestCase): + def setUp(self): + self.instance = Foo() + self.field = Example() + + # RemovedInDjango60Warning: when the deprecation ends, replace with: + # def test_cache_name_not_implemented(self): + # with self.assertRaises(NotImplementedError): + # FieldCacheMixin().cache_name + def test_get_cache_name_not_implemented(self): + with self.assertRaises(NotImplementedError): + FieldCacheMixin().get_cache_name() + + # RemovedInDjango60Warning. + def test_get_cache_name_deprecated(self): + msg = "Override ExampleOld.cache_name instead of get_cache_name()." + with self.assertWarnsMessage(RemovedInDjango60Warning, msg): + result = ExampleOld().cache_name + self.assertEqual(result, "example") + + def test_cache_name(self): + result = Example().cache_name + self.assertEqual(result, "example") + + def test_get_cached_value_missing(self): + with self.assertRaises(KeyError): + self.field.get_cached_value(self.instance) + + def test_get_cached_value_default(self): + default = object() + result = self.field.get_cached_value(self.instance, default=default) + self.assertIs(result, default) + + def test_get_cached_value_after_set(self): + value = object() + + self.field.set_cached_value(self.instance, value) + result = self.field.get_cached_value(self.instance) + + self.assertIs(result, value) + + def test_is_cached_false(self): + result = self.field.is_cached(self.instance) + self.assertFalse(result) + + def test_is_cached_true(self): + self.field.set_cached_value(self.instance, 1) + result = self.field.is_cached(self.instance) + self.assertTrue(result) + + def test_delete_cached_value(self): + self.field.set_cached_value(self.instance, 1) + self.field.delete_cached_value(self.instance) + result = self.field.is_cached(self.instance) + self.assertFalse(result) -- cgit v1.3