Skip to content

Fixed #36830 -- Stored the cache alias on cache backend instances. - #20469

Open
amirreza-sf80 wants to merge 1 commit into
django:mainfrom
amirreza-sf80:cache_36830
Open

amirreza-sf80 wants to merge 1 commit into
django:mainfrom
amirreza-sf80:cache_36830

Conversation

@amirreza-sf80

@amirreza-sf80 amirreza-sf80 commented Dec 26, 2025

Copy link
Copy Markdown
Contributor

Trac ticket number

ticket-36830

Branch description

this feature has been discussed in django/new-features#95

this pr will pass the cache backend alias name to the backend when instantiating them

this will make cache consistant with other parts of django such as the ORM and django.tasks

it also helps 3rd party packages with more complex logics, as mentioned in the feature request

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

@github-actions github-actions Bot added the no ticket Based on PR title, no linked Trac ticket label Dec 26, 2025
@amirreza-sf80 amirreza-sf80 changed the title store the cache alias on cache backend instances Fixed #36830 -- store the cache alias on cache backend instances Dec 26, 2025
@github-actions github-actions Bot removed the no ticket Based on PR title, no linked Trac ticket label Dec 26, 2025
@amirreza-sf80

Copy link
Copy Markdown
Contributor Author

i'm unsure how i should write the release note
should i move the note to the breaking changes section?

Comment thread django/core/management/commands/createcachetable.py Outdated
Comment thread tests/cache/tests.py Outdated
@github-actions

Copy link
Copy Markdown

📊 Coverage Report for Changed Files

-------------
Diff Coverage
Diff: origin/main...HEAD, staged and unstaged changes
-------------
django/core/cache/__init__.py (100%)
django/core/cache/backends/base.py (100%)
django/core/cache/backends/db.py (100%)
django/core/cache/backends/filebased.py (100%)
django/core/cache/backends/locmem.py (100%)
django/core/cache/backends/memcached.py (0.0%): Missing lines 16-17,148,181
django/core/cache/backends/redis.py (50.0%): Missing lines 162
django/core/management/commands/createcachetable.py (100%)
-------------
Total:   19 lines
Missing: 5 lines
Coverage: 73%
-------------


Note: Missing lines are warnings only. Some lines may not be covered by SQLite tests as they are database-specific.

For more information about code coverage on pull requests, see the contributing documentation.

Comment thread django/core/cache/__init__.py

@medmunds medmunds left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amirreza-sf80 thanks for this! I'm working on the new EMAIL_PROVIDERS feature that will parallel CACHES/DATABASES/STORAGES/TASKS (ticket-35514). We plan to make alias available on EmailBackend instances like you're doing here for cache backends, so I'm actively following this PR and ticket.

I added a handful of suggestions for backwards compatibility.

Comment thread django/core/cache/backends/db.py
Comment thread django/core/cache/backends/base.py Outdated
Comment thread django/core/cache/backends/memcached.py Outdated
Comment thread django/core/cache/__init__.py
@github-actions

Copy link
Copy Markdown

Thank you for your contribution to Django! This pull request has one or more items that need attention before it can be accepted for review.

⚠️ Warning: Incorrect Trac Ticket Flag

The referenced ticket ticket-36830 does not have the Has patch flag set in Trac. This flag must be checked before a pull request can be reviewed.

What to do:

  1. Open the ticket at https://code.djangoproject.com/ticket/36830.
  2. Scroll down and check the Has patch checkbox on the ticket.
  3. Save the ticket.

For more information see https://docs.djangoproject.com/en/dev/internals/contributing/triaging-tickets/#has-patch.

If you have questions about these requirements, please review the contributing guidelines or ask for help on the Django Forum.

@easherma

Copy link
Copy Markdown

I see this PR adds some deprecation, but I does the deprecation need to be documented anywhere else?

Comment thread django/core/cache/__init__.py Outdated
@medmunds

Copy link
Copy Markdown
Contributor

I see this PR adds some deprecation, but does the deprecation need to be documented anywhere else?

I think the built-in cache backend implementations—at least the BaseCache API shape—need to be treated as documented API subject to the usual deprecation policy. Because the docs say: "If you’re building your own backend, you can use the standard cache backends as reference implementations." Although Django users don't interact directly with these classes, developers of custom caches may. (They can't be considered strictly internal code.)

So yes, this would seem to need a release note explaining the changes needed in custom/third-party cache backends. (And an entry in docs/internals/deprecation.txt.)

Comment thread django/core/management/commands/createcachetable.py
Comment thread tests/cache/tests.py
@amirreza-sf80
amirreza-sf80 force-pushed the cache_36830 branch 2 times, most recently from a28b448 to 18f52a2 Compare August 30, 2026 02:35
@amirreza-sf80

Copy link
Copy Markdown
Contributor Author

i added a deprecation note in release notes
there doesn't seem to be a 6.2 entry in docs/internals/deprecation.txt so i assumed it doesn't need to be added there

@amirreza-sf80
amirreza-sf80 force-pushed the cache_36830 branch 3 times, most recently from c474e70 to 364dc22 Compare August 30, 2026 03:30
Comment thread django/core/cache/backends/base.py Outdated

@medmunds medmunds left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great @amirreza-sf80. I have a handful of suggestions and comments beyond @easherma's helpful review.

Also, we'll need tests for the deprecation warnings. There are some tips for that in Deprecating a feature. At least one of the tests should have a custom cache backend like might be in a third-party package.

For docs/internal/deprecation.txt, features being deprecated in 6.2 are removed in 7.1, so you'd add a note to the 7.1 section.

Comment thread django/core/cache/backends/base.py Outdated
Comment thread django/core/cache/backends/db.py
Comment thread django/core/management/commands/createcachetable.py Outdated
Comment thread docs/releases/6.2.txt Outdated
Comment thread tests/cache/tests.py

@medmunds medmunds left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Sorry, forgot to hit "submit" on one comment in my earlier review.]

Comment thread django/core/cache/__init__.py Outdated

@medmunds medmunds left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amirreza-sf80 this looks pretty much ready to me. I flagged a couple of typos, and left an (optional) suggestion for simplifying the legacy case in the management command.

Also, could you squash this to a single commit and rebase it to the main branch? Both are needed before it can be merged.

It looks like the DEP 20 release naming changes have been merged into main, so when rebasing you may find that RemovedInDjango71Warning will need to be replaced with RemovedInDjango2029Warning.

Comment on lines +50 to +58
cache_alias = next(
(
alias
for alias, cache in settings.CACHES.items()
if cache.get("LOCATION") == tablename
),
"<<unknown>>",
)
self.create_table(db, tablename, dry_run, cache_alias)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: used a fixed string that is unlikely to be mistaken for a real CACHES alias:

Suggested change
cache_alias = next(
(
alias
for alias, cache in settings.CACHES.items()
if cache.get("LOCATION") == tablename
),
"<<unknown>>",
)
self.create_table(db, tablename, dry_run, cache_alias)
self.create_table(db, tablename, dry_run, "<<unknown>>")

(I agree with you that this code I had suggested for searching CACHES is "strange"—and unnecessarily complicated for a legacy branch.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this works, since when we call create_table from this branch it doesn't really care what the alias is
but it does mean that different cache backends would get the same alias

this is probably not important in any way, but i feel like we shouldn't do it.

don't know what's right here

@medmunds medmunds Sep 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.create_table() creates a temporary cache backend instance that isn't exposed anywhere. And in this undocumented legacy branch, create_table only gets called one table at a time. I understand your concern, but I don't think there could be multiple cache backend instances with this "<<unknown>>" alias alive in memory at the same time.

Another reasonable option would be None, but that would require some additional work to avoid the warning in BaseCache.__init__() (e.g., using a sentinel object rather than None to detect the missing alias param).

Comment thread docs/releases/6.2.txt Outdated
Comment thread tests/cache/tests.py Outdated
@amirreza-sf80
amirreza-sf80 force-pushed the cache_36830 branch 2 times, most recently from 2f60b56 to 1f09aff Compare September 9, 2026 18:05
@amirreza-sf80

Copy link
Copy Markdown
Contributor Author

rebased and squashed up to this point

@medmunds medmunds left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for rebasing and updating the deprecations. There's a minor merge glitch and one untested deprecation warning.

Comment thread docs/internals/deprecation.txt Outdated
Comment thread docs/releases/6.2.txt Outdated
Comment thread django/core/cache/backends/base.py
Comment on lines +50 to +58
cache_alias = next(
(
alias
for alias, cache in settings.CACHES.items()
if cache.get("LOCATION") == tablename
),
"<<unknown>>",
)
self.create_table(db, tablename, dry_run, cache_alias)

@medmunds medmunds Sep 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.create_table() creates a temporary cache backend instance that isn't exposed anywhere. And in this undocumented legacy branch, create_table only gets called one table at a time. I understand your concern, but I don't think there could be multiple cache backend instances with this "<<unknown>>" alias alive in memory at the same time.

Another reasonable option would be None, but that would require some additional work to avoid the warning in BaseCache.__init__() (e.g., using a sentinel object rather than None to detect the missing alias param).

@medmunds

Copy link
Copy Markdown
Contributor

(Also, Django is quite picky about commit messages: if you could capitalize the "S" in "Fixed #36830 -- stored the cache alias…" and change the message body to past-tense sentences, that will save the merger a step.)

@amirreza-sf80 amirreza-sf80 changed the title Fixed #36830 -- store the cache alias on cache backend instances Fixed #36830 -- Store the cache alias on cache backend instances. Sep 12, 2026
@amirreza-sf80 amirreza-sf80 changed the title Fixed #36830 -- Store the cache alias on cache backend instances. Fixed #36830 -- Stored the cache alias on cache backend instances. Sep 12, 2026
@VimalN2005

Copy link
Copy Markdown
Contributor

Hi @amirreza-sf80, thanks for working on this! Adding alias to cache instances is a great improvement for parity with ORM and tasks.

A few observations and suggestions:

  1. Import inconsistency in django/core/cache/__init__.py:
    django_file_prefixes is imported from django.utils.deprecation here, whereas in django/core/cache/backends/base.py it is imported from django.utils.warnings. We should import it from django.utils.warnings in both places.

  2. Built-in backends constructor signatures:
    +1 to @medmunds' and @easherma's point regarding explicit alias=None over **kwargs for core backends (BaseDatabaseCache, RedisCache, LocMemCache, etc.). It avoids masking accidental typos and keeps signatures explicit for IDEs and type checkers.

  3. Clarify the deprecation warning message in CacheHandler.create_connection:
    The check verifies whether the backend constructor accepts the parameter, so the message:
    "Cache backends must pass the 'alias' arg to BaseCache."
    might be clearer if rephrased as:
    f"Cache backend '{backend_cls.__name__}' must accept an 'alias' parameter."

  4. Docs typo in docs/releases/6.2.txt:

    • "it's Subclasses" -> "its subclasses" (possessive and lowercase).
    • Capitalize "instances" to "Instances".

@medmunds medmunds left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amirreza-sf80 thanks for sticking with this.

In addition to @VimalN2005's comments, I spotted a few other minor corrections in the docs.

Comment thread docs/internals/deprecation.txt Outdated
Comment thread docs/releases/6.2.txt Outdated
Comment thread docs/releases/6.2.txt Outdated
@amirreza-sf80

Copy link
Copy Markdown
Contributor Author

thank you
applied

these changes passed the CACHES dictionary keys to the cache backend
when instantiating and stored it on the instance as self.alias, this was
discussed on the new-features repository and is mostly used by 3rd-pary
projects that need to know which cache they are using.

thanks to Tim Schilling for the report, thanks to Sergei Maertens, Eric
Sherman, Vimal Sahani, Mike Edmunds and Jonathan Biemond for reviews.

Co-authored-by: Mike Edmunds <[email protected]>
@amirreza-sf80

Copy link
Copy Markdown
Contributor Author

explicit alias=None over **kwargs for core backends (BaseDatabaseCache, RedisCache, LocMemCache, etc.)

i think it should only be explicit in BaseCache
since BaseCache is the only class that uses this parameter
looking at other parts of django i see the same pattern applied, and i think it's helpful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants