django-stash
Scoped ambient memoization for Django.
Stash values for the duration of a request (or any other explicit scope), and read them again from anywhere in the call stack — without threading a request through every helper.
This is not a cache backend. It does not replace Redis/Memcached/database cache. It is an L1 memo pad that only exists while a scope is open.
Install
pip install django-stash
MIDDLEWARE = [
"stash.middleware.StashMiddleware",
# ...
]
No INSTALLED_APPS entry required.
Usage
import stash
def expensive_site_paths():
return stash.get_or_set(
"wagtail.site_root_paths",
loader=compute_site_root_paths,
)
@stash.memoize(key="taxonomy.colours")
def get_colour_choices():
return list(Colour.objects.values_list("id", "name"))
Outside a scope (management commands, Celery, shell), get_or_set / memoize just call the loader every time. Nothing sticks on the worker.
Manual scopes
with stash.stash_scope():
...
Useful for tests, management commands, or task bodies that want the same behaviour.
Clearing
stash.clear("wagtail.site_root_paths") # one key
stash.clear() # everything in this scope
Rules of thumb
- Scope owns lifetime — middleware /
stash_scope()enable at enter and disable infinally. - No scope ⇒ no stash — avoids sticky process caches on Gunicorn sync workers.
- Prefer immutable-ish values — stash stores/returns shallow copies; don't stash live model graphs you plan to mutate in place.
- Shared cache is separate — if you need cross-process invalidation, keep Django's cache as L2 and use stash as L1 in front of it.
Development
cd django-stash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[testing,development]"
python testmanage.py test
Metadata
Release files for django-stash 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| django_stash-0.1.0.tar.gz | 5.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| django_stash-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.9 kB
Release files / django_stash-0.1.0.tar.gz
| Download URL | django_stash-0.1.0.tar.gz |
|---|---|
| Size | 5.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fe3b1f9048497577525431ef40a1b6eeaae75ee6fd9222d58df2d8e7b354a930
|
|
BLAKE2b-256 checksum How to use checksums |
ae54b825fe56d8d05bb1db7230b77ddc102b9516f1b1397aab8a9e88ac5ff943
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency logRelease files / django_stash-0.1.0-py3-none-any.whl
| Download URL | django_stash-0.1.0-py3-none-any.whl |
|---|---|
| Size | 5.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
88dd5d50814955b8e38660cb5c62e5ca6782039a9d04ea0eb34f8a1b399fa9ff
|
|
BLAKE2b-256 checksum How to use checksums |
31a4e360fbba933b74eed73fb8414a4b8e6999414309e4b056770aaa7ea4b8bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency log