diff --git a/aleksis/core/managers.py b/aleksis/core/managers.py index a0871078015df8e117a09e23a593b384f7b25dc2..02a0cb6fb6504d931b3d848217b154951d8a0932 100644 --- a/aleksis/core/managers.py +++ b/aleksis/core/managers.py @@ -79,3 +79,15 @@ class SchoolTermRelatedQuerySet(QuerySet): return self.for_school_term(current_school_term) else: return None + + +class GroupManager(CurrentSiteManagerWithoutMigrations): + """Manager adding specific methods to groups.""" + + def get_queryset(self): + """Ensure all related data is loaded as well.""" + return super().get_queryset().select_related("school_term") + + +class GroupQuerySet(SchoolTermRelatedQuerySet): + pass diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py index d4a8fcf7023f431857c05fad2362658fdadbe321..b9d96809dd3caea14039612a267f6d4112c672a0 100644 --- a/aleksis/core/mixins.py +++ b/aleksis/core/mixins.py @@ -115,7 +115,7 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase): return CRUDEvent.objects.filter( object_id=self.pk, content_type=content_type - ).select_related("user") + ).select_related("user", "user__person") @property def crud_event_create(self) -> Optional[CRUDEvent]: diff --git a/aleksis/core/models.py b/aleksis/core/models.py index bd1cfe12d531e95e4a5d0b7d1e480cf60b91717f..2231fb36057c2c33edec8d6b4e1384e5693ac331 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -19,11 +19,17 @@ from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ import jsonstore +from cache_memoize import cache_memoize from dynamic_preferences.models import PerInstancePreferenceModel from phonenumber_field.modelfields import PhoneNumberField from polymorphic.models import PolymorphicModel -from .managers import CurrentSiteManagerWithoutMigrations, SchoolTermQuerySet +from .managers import ( + CurrentSiteManagerWithoutMigrations, + GroupManager, + GroupQuerySet, + SchoolTermQuerySet, +) from .mixins import ExtensibleModel, PureDjangoModel, SchoolTermRelatedExtensibleModel from .tasks import send_notification from .util.core_helpers import get_site_preferences, now_tomorrow @@ -59,6 +65,7 @@ class SchoolTerm(ExtensibleModel): date_end = models.DateField(verbose_name=_("End date")) @classmethod + @cache_memoize(3600) def get_current(cls, day: Optional[date] = None): if not day: day = timezone.now().date() @@ -313,6 +320,8 @@ class Group(SchoolTermRelatedExtensibleModel): classes, clubs, and the like. """ + objects = GroupManager.from_queryset(GroupQuerySet)() + class Meta: ordering = ["short_name", "name"] verbose_name = _("Group") @@ -681,9 +690,10 @@ class CustomMenu(ExtensibleModel): return self.name if self.name != "" else self.id @classmethod + @cache_memoize(3600) def get_default(cls, name): """Get a menu by name or create if it does not exist.""" - menu, _ = cls.objects.get_or_create(name=name) + menu, _ = cls.objects.prefetch_related("items").get_or_create(name=name) return menu class Meta: diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py index 788a4debec2a9ec7b3fb6c52f97121dbe9179340..9875c6429cd2e0fa623f9b9c8423d512576dbe9e 100644 --- a/aleksis/core/util/core_helpers.py +++ b/aleksis/core/util/core_helpers.py @@ -134,6 +134,7 @@ def lazy_get_favicon_url( ) -> Callable[[str, str], Any]: """Lazily get the URL to a favicon image.""" + @cache_memoize(3600) def _get_favicon_url(size: int, rel: str) -> Any: from favicon.models import Favicon # noqa