|
4 | 4 |
|
5 | 5 |
|
6 | 6 | @isolate_apps("model_options")
|
7 |
| -class MetaCachingTests(SimpleTestCase): |
| 7 | +class ForwardPropertiesCachingTests(SimpleTestCase): |
8 | 8 | """Tests FORWARD_PROPERTIES for Django's model metadata caching system."""
|
9 | 9 |
|
10 | 10 | def test_forward_properties_initialization(self):
|
@@ -33,7 +33,7 @@ class TestModel(models.Model):
|
33 | 33 | # Verify it's now in the __dict__
|
34 | 34 | self.assertIn(prop, TestModel._meta.__dict__)
|
35 | 35 |
|
36 |
| - def test_expire_cache_forward(self): |
| 36 | + def test_expire_cache_forward_properties(self): |
37 | 37 | """Test that _expire_cache properly clears FORWARD_PROPERTIES."""
|
38 | 38 |
|
39 | 39 | class TestModel(models.Model):
|
@@ -151,3 +151,66 @@ class DynamicModel(models.Model):
|
151 | 151 | # Verify the new field is included
|
152 | 152 | field_names = [f.name for f in updated_fields]
|
153 | 153 | self.assertIn("dynamic_field", field_names)
|
| 154 | + |
| 155 | + |
| 156 | +@isolate_apps("model_options") |
| 157 | +class ReversePropertiesCachingTests(SimpleTestCase): |
| 158 | + """Tests REVERSE_PROPERTIES for Django's model metadata caching system.""" |
| 159 | + |
| 160 | + def test_reverse_properties_initialization(self): |
| 161 | + """Test that REVERSE_PROPERTIES are properly initialized.""" |
| 162 | + |
| 163 | + class TestModel(models.Model): |
| 164 | + name = models.CharField(max_length=100) |
| 165 | + parent = models.ForeignKey( |
| 166 | + "self", on_delete=models.CASCADE, null=True, related_name="children" |
| 167 | + ) |
| 168 | + |
| 169 | + # Verify that none of the REVERSE_PROPERTIES are in the __dict__ initially |
| 170 | + for prop in TestModel._meta.REVERSE_PROPERTIES: |
| 171 | + with self.subTest(property=prop): |
| 172 | + self.assertNotIn(prop, TestModel._meta.__dict__) |
| 173 | + |
| 174 | + def test_reverse_properties_access(self): |
| 175 | + """Test that accessing a REVERSE_PROPERTY caches it in the __dict__.""" |
| 176 | + |
| 177 | + class TestModel(models.Model): |
| 178 | + name = models.CharField(max_length=100) |
| 179 | + parent = models.ForeignKey
10000
span>( |
| 180 | + "self", on_delete=models.CASCADE, null=True, related_name="children" |
| 181 | + ) |
| 182 | + |
| 183 | + # Access each reverse property and verify it's cached |
| 184 | + for prop in TestModel._meta.REVERSE_PROPERTIES: |
| 185 | + if hasattr(TestModel._meta, prop): |
| 186 | + with self.subTest(property=prop): |
| 187 | + # Access the property to trigger caching |
| 188 | + getattr(TestModel._meta, prop) |
| 189 | + # Verify it's now in the __dict__ |
| 190 | + self.assertIn(prop, TestModel._meta.__dict__) |
| 191 | + |
| 192 | + def test_expire_cache_reverse_properties(self): |
| 193 | + """Test that _expire_cache properly clears REVERSE_PROPERTIES.""" |
| 194 | + |
| 195 | + class TestModel(models.Model): |
| 196 | + name = models.CharField(max_length=100) |
| 197 | + parent = models.ForeignKey( |
| 198 | + "self", on_delete=models.CASCADE, null=True, related_name="children" |
| 199 | + ) |
| 200 | + |
| 201 | + meta = TestModel._meta |
| 202 | + |
| 203 | + # First, access some reverse properties to cache them |
| 204 | + _ = meta.related_objects |
| 205 | + _ = meta.fields_map |
| 206 | + |
| 207 | + # Verify they're cached |
| 208 | + self.assertIn("related_objects", meta.__dict__) |
| 209 | + self.assertIn("fields_map", meta.__dict__) |
| 210 | + |
| 211 | + # Now expire the cache |
| 212 | + meta._expire_cache(forward=False, reverse=True) |
| 213 | + |
| 214 | + # Verify the properties are no longer cached |
| 215 | + self.assertNotIn("related_objects", meta.__dict__) |
| 216 | + self.assertNotIn("fields_map", meta.__dict__) |
0 commit comments