Coverage for website/members/api/calendarjs/views.py: 35.00%
34 statements
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
1import copy
3from django.db.models import Prefetch, Q, prefetch_related_objects
4from django.utils import timezone
6from rest_framework.generics import ListAPIView
7from rest_framework.permissions import IsAuthenticated
9from members.api.calendarjs.serializers import MemberBirthdaySerializer
10from members.models import Member, Membership
11from utils.snippets import extract_date_range
14class CalendarJSBirthdayListView(ListAPIView):
15 """Define a custom route that outputs the correctly formatted events information for CalendarJS, published events only."""
17 serializer_class = MemberBirthdaySerializer
18 permission_classes = [IsAuthenticated]
19 pagination_class = None
21 def _get_birthdays(self, member, start, end):
22 birthdays = []
24 start_year = max(start.year, member.profile.birthday.year)
25 for year in range(start_year, end.year + 1):
26 bday = copy.deepcopy(member)
27 try:
28 bday.profile.birthday = bday.profile.birthday.replace(year=year)
29 except ValueError as e:
30 if bday.profile.birthday.month == 2 and bday.profile.birthday.day == 29:
31 bday.profile.birthday = bday.profile.birthday.replace(
32 year=year, day=28
33 )
34 else:
35 raise e
36 if start.date() <= bday.profile.birthday <= end.date():
37 birthdays.append(bday)
38 return birthdays
40 def get_queryset(self):
41 start, end = extract_date_range(self.request)
43 queryset = (
44 Member.current_members.with_birthdays_in_range(start, end)
45 .filter(profile__show_birthday=True)
46 .select_related("profile")
47 )
49 all_birthdays = [self._get_birthdays(m, start, end) for m in queryset.all()]
50 birthdays = [x for sublist in all_birthdays for x in sublist]
52 today = timezone.now().date()
53 prefetch_related_objects(
54 birthdays,
55 Prefetch(
56 "membership_set",
57 queryset=Membership.objects.filter(
58 Q(until__isnull=True) | Q(until__gt=today), since__lte=today
59 ).order_by("-since")[:1],
60 to_attr="_current_membership",
61 ),
62 )
64 return birthdays