Add start of simple module to help with caching singleton URLs
This commit is contained in:
parent
557a28833b
commit
ac46c0ae0b
5 changed files with 65 additions and 0 deletions
0
website/contrib/singleton_url/__init__.py
Normal file
0
website/contrib/singleton_url/__init__.py
Normal file
16
website/contrib/singleton_url/tests.py
Normal file
16
website/contrib/singleton_url/tests.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from django.test import TestCase
|
||||
|
||||
from website.common.models import ContentPage
|
||||
from website.home.models import HomePage
|
||||
|
||||
from .utils import SingletonURLCache
|
||||
|
||||
|
||||
class SingletonURLTestCase(TestCase):
|
||||
def test_gets_url(self) -> None:
|
||||
with self.assertNumQueries(2):
|
||||
self.assertEqual(SingletonURLCache.get_url(HomePage), "http://localhost/")
|
||||
|
||||
def test_missing_page(self) -> None:
|
||||
with self.assertNumQueries(1):
|
||||
self.assertIsNone(SingletonURLCache.get_url(ContentPage))
|
32
website/contrib/singleton_url/utils.py
Normal file
32
website/contrib/singleton_url/utils.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
from typing import Type
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.http.request import HttpRequest
|
||||
from wagtail.models import Page
|
||||
|
||||
|
||||
class SingletonURLCache:
|
||||
@classmethod
|
||||
def get_url_cache_key(cls, model: Type[Page]) -> str:
|
||||
return f"singleton_url_{model.__name__}"
|
||||
|
||||
@classmethod
|
||||
def get_url(
|
||||
cls, model: Type[Page], request: HttpRequest | None = None
|
||||
) -> str | None:
|
||||
cache_key = cls.get_url_cache_key(model)
|
||||
|
||||
url = cache.get(cache_key)
|
||||
|
||||
if url is None:
|
||||
# `.first` is marginally more efficient than `.get`
|
||||
page = Page.objects.type(model).first()
|
||||
|
||||
if page is None:
|
||||
return None
|
||||
|
||||
url = page.get_full_url(request)
|
||||
|
||||
cache.set(cache_key, url, 86400)
|
||||
|
||||
return url
|
16
website/contrib/singleton_url/wagtail_hooks.py
Normal file
16
website/contrib/singleton_url/wagtail_hooks.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from django.core.cache import cache
|
||||
from wagtail import hooks
|
||||
|
||||
from website.common.utils import get_page_models
|
||||
|
||||
from .utils import SingletonURLCache
|
||||
|
||||
|
||||
@hooks.register("after_move_page")
|
||||
def clear_singleton_url_cache(**kwargs: dict) -> None:
|
||||
"""
|
||||
Clear all page caches, in case a parent has moved
|
||||
"""
|
||||
cache.delete_many(
|
||||
[SingletonURLCache.get_url_cache_key(model) for model in get_page_models()]
|
||||
)
|
|
@ -41,6 +41,7 @@ INSTALLED_APPS = [
|
|||
"website.contrib.code_block",
|
||||
"website.contrib.mermaid_block",
|
||||
"website.contrib.unsplash",
|
||||
"website.contrib.singleton_url",
|
||||
"wagtail.contrib.forms",
|
||||
"wagtail.contrib.redirects",
|
||||
"wagtail.contrib.modeladmin",
|
||||
|
|
Loading…
Reference in a new issue