Skip to content
Snippets Groups Projects
Verified Commit 1fa84476 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Add managers and querysets for group role models to simplify queries

parent 4ccf137e
No related branches found
No related tags found
1 merge request!131Resolve "Add support for assinging group roles"
from datetime import date, datetime
from typing import Optional, Sequence, Union
from django.db.models import QuerySet
from django.db.models.query import Prefetch
from django.db.models.query_utils import Q
from calendarweek import CalendarWeek
from aleksis.apps.chronos.managers import DateRangeQuerySetMixin
from aleksis.core.managers import CurrentSiteManagerWithoutMigrations
......@@ -42,3 +49,51 @@ class LessonDocumentationQuerySet(QuerySet):
def not_empty(self):
"""Get all not empty lesson documentations."""
return self.filter(~Q(topic="") | ~Q(group_note="") | ~Q(homework=""))
class GroupRoleManager(CurrentSiteManagerWithoutMigrations):
pass
class GroupRoleQuerySet(QuerySet):
def with_assignments(
self, time_ref: Union[date, CalendarWeek], groups: Sequence["Group"]
) -> QuerySet:
from aleksis.apps.alsijil.models import GroupRoleAssignment
if isinstance(time_ref, CalendarWeek):
qs = GroupRoleAssignment.objects.in_week(time_ref)
else:
qs = GroupRoleAssignment.objects.on_day(time_ref)
qs = qs.for_groups(groups).distinct()
return self.prefetch_related(Prefetch("assignments", queryset=qs,))
class GroupRoleAssignmentManager(CurrentSiteManagerWithoutMigrations):
pass
class GroupRoleAssignmentQuerySet(DateRangeQuerySetMixin, QuerySet):
def within_dates(self, start: date, end: date):
"""Filter for all role assignments within a date range."""
return self.filter(
Q(date_start__lte=end) & (Q(date_end__gte=start) | Q(date_end__isnull=True))
)
def at_time(self, when: Optional[datetime] = None):
"""Filter for role assignments assigned at a certain point in time."""
now = when or datetime.now()
return self.on_day(now.date())
def for_groups(self, groups: Sequence["Group"]):
"""Filter all role assignments for a sequence of groups."""
qs = self
for group in groups:
qs = qs.for_group(group)
return qs
def for_group(self, group: "Group"):
"""Filter all role assignments for a group."""
return self.filter(Q(groups=group) | Q(groups__child_groups=group))
......@@ -13,6 +13,10 @@ from aleksis.apps.alsijil.data_checks import (
PersonalNoteOnHolidaysDataCheck,
)
from aleksis.apps.alsijil.managers import (
GroupRoleAssignmentManager,
GroupRoleAssignmentQuerySet,
GroupRoleManager,
GroupRoleQuerySet,
LessonDocumentationManager,
LessonDocumentationQuerySet,
PersonalNoteManager,
......@@ -242,6 +246,8 @@ class ExtraMark(ExtensibleModel):
class GroupRole(ExtensibleModel):
objects = GroupRoleManager.from_queryset(GroupRoleQuerySet)()
name = models.CharField(max_length=255, verbose_name=_("Name"))
icon = models.CharField(max_length=50, blank=True, choices=ICONS, verbose_name=_("Icon"))
colour = models.CharField(max_length=50, blank=True, choices=COLOURS, verbose_name=_("Colour"))
......@@ -255,6 +261,8 @@ class GroupRole(ExtensibleModel):
class GroupRoleAssignment(GroupPropertiesMixin, ExtensibleModel):
objects = GroupRoleAssignmentManager.from_queryset(GroupRoleAssignmentQuerySet)()
role = models.ForeignKey(
GroupRole,
on_delete=models.CASCADE,
......@@ -282,6 +290,13 @@ class GroupRoleAssignment(GroupPropertiesMixin, ExtensibleModel):
date_end = date_format(self.date_end) if self.date_end else "?"
return f"{self.role}: {self.person}, {date_format(self.date_start)}{date_end}"
@property
def date_range(self) -> str:
if not self.date_end:
return f"{date_format(self.date_start)}–?"
else:
return f"{date_format(self.date_start)}{date_format(self.date_end)}"
class Meta:
verbose_name = _("Group role assignment")
verbose_name_plural = _("Group role assignments")
......
......@@ -934,16 +934,7 @@ class AssignedGroupRolesView(PermissionRequiredMixin, DetailView):
today = timezone.now().date()
context["today"] = today
self.roles = GroupRole.objects.prefetch_related(
Prefetch(
"assignments",
queryset=GroupRoleAssignment.objects.filter(
Q(date_start__lte=today) & (Q(date_end__gte=today) | Q(date_end__isnull=True))
)
.filter(Q(groups=self.object) | Q(groups__child_groups=self.object))
.distinct(),
)
)
self.roles = GroupRole.objects.with_assignments(today, [self.object])
context["roles"] = self.roles
assignments = (
GroupRoleAssignment.objects.filter(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment