Skip to main content

Small Django utilities built on Django core.

Project description

dj-corekit

CI PyPI Python Django License

Small Django utilities built on Django core.

Installation

python -m pip install dj-corekit

Toolkit

Cache

  • Cache function views with Django-style default keys or caller-owned cache keys.
  • Cache class-based views with method_decorator or CachePageMixin.
  • Apply headers before storing responses.
  • Set Cloudflare edge cache headers separately from browser cache headers.
  • Cache TemplateResponse objects after rendering.
  • Bypass caching per request with request.do_not_cache or only_if.

More utilities can be added here as new modules land.

Cache

Function Views

from dj_corekit.cache import cache_page


@cache_page(
    timeout=300,
    headers=lambda request, response: {
        "X-Cache-Scope": "product",
        "Cache-Control": "public, max-age=300",
    },
)
def product_detail(request):
    ...

Cloudflare Edge Cache

cloudflare_cache_page sets origin response headers for Cloudflare, but it does not configure your Cloudflare zone. For HTML or other dynamic pages, Cloudflare requires a Cache Rule that makes the route eligible for cache.

from dj_corekit.cache import cloudflare_cache_page


@cloudflare_cache_page(
    timeout=300,
    key_func=lambda request: f"product:{request.GET.get('id')}",
    cloudflare={
        "browser_ttl": 0,
        "vary": ("CF-IPCountry", "CF-Device-Type"),
    },
)
def product_detail(request):
    ...

Cloudflare behavior used by this decorator:

  • Cloudflare-CDN-Cache-Control: max-age=N controls Cloudflare edge TTL without forwarding that header downstream. Cloudflare treats this as the Cloudflare-specific version of CDN-Cache-Control.
  • Cache-Control: public, max-age=N controls browser-facing freshness. The default browser TTL is 0, so browsers must revalidate while Cloudflare can still keep an edge copy.
  • cloudflare["vary"] does two things: it adds the listed request headers to this package's Django cache key, and it emits Vary so Cloudflare can cache separate variants when the zone has matching Cache Rules Vary/custom cache key configuration.
  • Dynamic content such as HTML is not cached by Cloudflare by default. Use a Cache Rule for routes that should be cached at the edge.

Cloudflare references:

Class-Based Views

Use Django's method_decorator when you want to keep caching outside the view class:

from django.utils.decorators import method_decorator
from django.views import View
from dj_corekit.cache import cache_page


@method_decorator(
    cache_page(timeout=300, key_func=lambda request: "product:list"),
    name="dispatch",
)
class ProductListView(View):
    ...

Use CachePageMixin when each view owns its cache settings:

from django.views import View
from dj_corekit.cache import CachePageMixin


class ProductDetailView(CachePageMixin, View):
    cache_timeout = 300
    cache_headers = {"X-Cache-Scope": "product"}

    def get_cache_key(self, request):
        return f"product:{self.kwargs['pk']}"

Use CloudflareCachePageMixin for the same class-based pattern with Cloudflare-aware headers:

from django.views import View
from dj_corekit.cache import CloudflareCachePageMixin


class ProductDetailView(CloudflareCachePageMixin, View):
    cache_timeout = 300
    cache_cloudflare = {"vary": ("CF-IPCountry",)}

Behavior

Without extension params, cache_page delegates to Django's django.views.decorators.cache.cache_page, using cache_alias as Django's cache argument. With headers or only_if but no key_func, Django still owns cache keying and storage; dj-corekit only wraps the view to apply headers or bypass caching. With key_func, the callable returns the full cache key and dj-corekit stores the response through django.core.cache.caches[cache_alias].

POST responses are only cached when you provide key_func; include the request method, body/form data, user, or any other response-changing input in that key.

Only 200 responses are cached. TemplateResponse objects are cached after rendering. Set request.do_not_cache = True or return False from only_if to bypass caching.

API

cache_page

cache_page(
    timeout,
    key_func=None,
    *,
    headers=None,
    cache_alias="default",
    only_if=None,
)

cloudflare_cache_page

cloudflare_cache_page(
    timeout,
    key_func=None,
    *,
    cloudflare=None,
    headers=None,
    cache_alias="default",
    only_if=None,
)

CachePageMixin

class CachePageMixin:
    cache_timeout = 300
    cache_key_func = None
    cache_headers = None
    cache_alias = "default"
    cache_only_if = None

    def get_cache_key(self, request):
        ...

CloudflareCachePageMixin

class CloudflareCachePageMixin(CachePageMixin):
    cache_cloudflare = None
  • timeout: seconds, or a callable receiving the response.
  • key_func: optional callable receiving the request and returning the full cache key.
  • headers: dict or callable receiving (request, response) and returning a header dict. These headers are applied before the response is cached.
  • cloudflare: optional dict for cloudflare_cache_page:
    • edge_ttl: Cloudflare-CDN-Cache-Control max-age. Defaults to timeout.
    • browser_ttl: browser Cache-Control max-age. Defaults to 0.
    • vary: request header names to include in the cache key and Vary.
  • cache_cloudflare: mixin equivalent of cloudflare.
  • Cloudflare TTL values must resolve to non-negative integers.
  • cache_alias: Django cache alias, default "default".
  • only_if: callable receiving the request. Return False to bypass cache.

Development

Local Checks

python -m pip install -e ".[dev]"
python -m pytest
ruff check .
ruff format --check .
tox

CI

GitHub Actions runs tests on Python 3.10, 3.11, 3.12, and 3.13. Ruff linting and formatting checks run once on Python 3.12.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dj_corekit-0.2.1.tar.gz (9.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dj_corekit-0.2.1-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file dj_corekit-0.2.1.tar.gz.

File metadata

  • Download URL: dj_corekit-0.2.1.tar.gz
  • Upload date:
  • Size: 9.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dj_corekit-0.2.1.tar.gz
Algorithm Hash digest
SHA256 9b179d15302a6efef38d5d37e150505148d70a4caaf94ab3efbbce67abee95c8
MD5 d750737c21d358bb0e29247f2a101476
BLAKE2b-256 08e8396fe589464cd6f062ed5a73c10548a0e4f065d06d198e6b8bf311dde644

See more details on using hashes here.

Provenance

The following attestation bundles were made for dj_corekit-0.2.1.tar.gz:

Publisher: release.yml on himkit/dj-corekit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dj_corekit-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: dj_corekit-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 7.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dj_corekit-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 623cef954cc8595889ac01759d4e235d66d1b53abe59563cb2ac6b6b271ddf7e
MD5 2d4617634d68b6319e74b9577d70db07
BLAKE2b-256 9162f17d72a224a3316766f4d15685b40fad1f362ab4e274e58d50e0190fe83e

See more details on using hashes here.

Provenance

The following attestation bundles were made for dj_corekit-0.2.1-py3-none-any.whl:

Publisher: release.yml on himkit/dj-corekit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page