Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion django/db/migrations/autodetector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1682,7 +1682,10 @@ def _get_dependencies_for_foreign_key(app_label, model_name, field, project_stat

def _get_dependencies_for_generated_field(self, field):
dependencies = []
referenced_base_fields = models.Q(field.expression).referenced_base_fields
referenced_base_fields = [
name
for name, *lookups in models.Model._get_expr_references(field.expression)
]
newly_added_fields = sorted(self.new_field_keys - self.old_field_keys)
for app_label, model_name, added_field_name in newly_added_fields:
added_field = self.to_state.models[app_label, model_name].get_field(
Expand Down
7 changes: 7 additions & 0 deletions django/db/models/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ class Options:
"managers_map",
"base_manager",
"default_manager",
"db_returning_fields",
"_property_names",
"pk_fields",
"total_unique_constraints",
"all_parents",
"swapped",
"verbose_name_raw",
}
REVERSE_PROPERTIES = {"related_objects", "fields_map", "_relation_tree"}

Expand Down
10 changes: 2 additions & 8 deletions django/db/models/sql/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import copy
import difflib
import functools
import inspect
import sys
import warnings
from collections import Counter, namedtuple
Expand Down Expand Up @@ -44,7 +43,7 @@
from django.db.models.sql.constants import INNER, LOUTER, ORDER_DIR, SINGLE
from django.db.models.sql.datastructures import BaseTable, Empty, Join, MultiJoin
from django.db.models.sql.where import AND, OR, ExtraWhere, NothingNode, WhereNode
from django.utils.deprecation import RemovedInDjango70Warning
from django.utils.deprecation import RemovedInDjango70Warning, django_file_prefixes
from django.utils.functional import cached_property
from django.utils.regex_helper import _lazy_re_compile
from django.utils.tree import Node
Expand Down Expand Up @@ -1216,15 +1215,10 @@ def join_parent_model(self, opts, model, alias, seen):
def check_alias(self, alias):
# RemovedInDjango70Warning: When the deprecation ends, remove.
if "%" in alias:
if "aggregate" in {frame.function for frame in inspect.stack()}:
stacklevel = 5
else:
# annotate(), alias(), and values().
stacklevel = 6
warnings.warn(
"Using percent signs in a column alias is deprecated.",
stacklevel=stacklevel,
category=RemovedInDjango70Warning,
skip_file_prefixes=django_file_prefixes(),
)
if FORBIDDEN_ALIAS_PATTERN.search(alias):
raise ValueError(
Expand Down
22 changes: 22 additions & 0 deletions tests/apps/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
skipUnlessDBFeature,
)
from django.test.utils import extend_sys_path, isolate_apps
from django.utils.functional import cached_property

from .models import SoAlternative, TotallyNormal, new_apps
from .one_config_app.apps import OneConfig
Expand Down Expand Up @@ -215,6 +216,27 @@ def test_clear_cache(self):
self.assertEqual(apps.get_swappable_settings_name.cache_info().currsize, 0)
self.assertEqual(apps.get_models.cache_info().currsize, 0)

@override_settings(INSTALLED_APPS=SOME_INSTALLED_APPS)
def test_cached_properties_cleared_after_cache_clear(self):
opts = apps.get_model("admin", "LogEntry")._meta

cached_properties = [
name
for name, attr in models.options.Options.__dict__.items()
if isinstance(attr, cached_property)
]

# Access each cached property to populate the cache.
for attr_name in cached_properties:
getattr(opts, attr_name)
self.assertIn(attr_name, opts.__dict__)

apps.clear_cache()

for attr_name in cached_properties:
with self.subTest(property=attr_name):
self.assertNotIn(attr_name, opts.__dict__)

@override_settings(INSTALLED_APPS=["apps.apps.RelabeledAppsConfig"])
def test_relabeling(self):
self.assertEqual(apps.get_app_config("relabeled").name, "apps")
Expand Down
Loading