-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
Refs #5815, #31938, #34271 -- Created invalidate_view_cache function … #19946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Hello! Thank you for your contribution 💪 As it's your first contribution be sure to check out the patch review checklist. If you're fixing a ticket from Trac make sure to set the "Has patch" flag and include a link to this PR in the ticket! If you have any design or process questions then you can ask in the Django forum. Welcome aboard ⛵️! |
db53bae
to
063c5ee
Compare
…ction to manually invalidate cache key. Thanks Laurent Tramoy for the implementation idea and Carlton Gibson for the support.
063c5ee
to
20e2676
Compare
Hey @rjnocelli — Welcome aboard! ⛵️— Nice hustle turning your work into a PR over the weekend. (You can assign the ticket to yourself on Trac 🙂) Let me read it through and give an initial feedback. (We don't currently use type annotations in Django itself, so we'll drop those, and docs would be needed, etc — but we can refine towards all that.) Nice one! 👊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @rjnocelli — I had a first look.
Can you add some test cases for the vary_header
argument, showing that in action?
We'll need then to adjust the docstring a little and add docs, but seems pretty straightforward. Nice 👍
django/utils/cache.py
Outdated
vary_headers should be a dict of every header used for this particular view | ||
In local environment, we have two defined renderers (default of DRF), | ||
thus DRF adds `Accept` to the Vary headers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rjnocelli Can you add tests showing this in action?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, definitely!
django/utils/cache.py
Outdated
path: str = None, | ||
request: WSGIRequest = None, | ||
vary_headers: Optional[Dict[str, str]] = None, | ||
key_prefix: Optional[str] = None, | ||
) -> Annotated[int, "Number of cache keys deleted"]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should remove the annotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, will do!
django/utils/cache.py
Outdated
Note: If LocaleMiddleware is used, | ||
we'll need to use the same language code as the one in the cached request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably needs a test case too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both the decorator and get_cache_key
function rely on the same underlying logic in _generate_cache_key which accounts for configuration settings.USE_I18N
. Since this logic is implicit to the generation and retrieval of the cache key in this workflow, is a test really needed here? It might make sense to add to possibility to delete all locale variations of a key (something similar to what Laurent Tramoy propposed on ticket 31938) but this will require more work since not all cache backends support key search by pattern (I think Redis scan function would work for this).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, not sure immediately. Maybe a test isn't needed...
I was mostly thinking for the docs. We're going to need to give examples for folks to know how to use this function, and given that it's worth a comment, it's probably worth an examples too.
(Start with the normal vary versions and then we can see what docs we come up with)
I've applied some new changes:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates @rjnocelli. I've just left a few more discursive comments. (They're status Maybe 🤔 rather than more than that.)
I checked the flag on the ticket: looking good. Ready for a review from someone else now.
(I'm really excited about this. I'm going to have to pull it into my personal project so that I can stop flushing my cache entirely every time I spot a typo 💃)
django/utils/cache.py
Outdated
If there is no headerlist stored, the page needs to be rebuilt, so this | ||
function returns ``None``. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems unrelated. Could either be dropped or merged as a separate clean up. (Pending Fellow decisions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll roll this one back.
django/utils/cache.py
Outdated
Delete a view cache key based on either a relative URL (``path``) | ||
or a request object (``request``). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "view cache" relate to cache_page
clearly enough? Maybe...
Delete a view cache key based on either a relative URL (``path``) | |
or a request object (``request``). | |
Delete a cached page key based on either a relative URL (``path``) | |
or a request object (``request``). |
django/utils/cache.py
Outdated
return t[0].lower(), True | ||
|
||
|
||
def invalidate_view_cache(path=None, request=None, key_prefix=None, cache=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we want just a request
parameter, which could be a path, then converted in the same code block as below? 🤔
django/utils/cache.py
Outdated
If both are given, ``path`` takes precedence. | ||
""" | ||
if not request: | ||
assert path is not None, "either `path` or `request` arguments needed" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raise a ValueError
(?) here, and test for the exception. (Rather than an assertion, to match Django code style.)
Hi @carltongibson! Here are few comments regarding my latest changes:
Looking forward hearing back from you! cheers! |
Great. good effort @rjnocelli. I want to wait for someone else to take a look now. It's in the right ballpark, but other eyes. I looked at the flags on Trac, and they were set right, so this ticket will appear on the review queue. |
Trac ticket number
ticket-5815
Branch description
At the moment there is not an 'easy' way to invalidate cached view responses from Django code. This PR introduces an utility function called invalidate_view_cache which allows you to do so using the relative path (request object takes care of putting together the rest of the URL).
Checklist
main
branch.