Created
July 10, 2024 20:58
-
-
Save cnk/603c48f6029e033d38e006db6988843a to your computer and use it in GitHub Desktop.
Calendar views
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MasterCalendarPage(RoutablePageMixin, Page): | |
## Fields - including one that sets the default time period: day, week, month | |
## Helpers | |
def _build_date_filtered_queryset(self, site, start_date, end_date): | |
queryset = self.base_queryset(site) | |
if start_date: | |
# If the user selected a start date, exclude all events that ended before then. | |
queryset = queryset.exclude(end_date__lte=start_date) | |
if end_date: | |
# If the user selected an end date, exclude all events that started a day afterward. | |
# This way, searching for Mar 19 - Mar 20 gets you the events on both the 19th and the 20th. | |
queryset = queryset.exclude(start_date__gte=end_date + timedelta(days=1)) | |
return queryset | |
def _date_in_allowed_range(self, dt): | |
""" | |
Robots will just keep itterating on dates so we need to limit them to relevant date ranges | |
""" | |
return dt.date() >= settings.CALENDAR_START_DATE and dt.date() <= date.today() + settings.CALENDAR_END_DELTA | |
def _get_week_range(self, specified_date=None): | |
if not specified_date: | |
# If not specified_date was provided, use the datetime object that represents today. | |
specified_date = localtime().replace(hour=0, minute=0, second=0, microsecond=0) | |
# The %w format gives the weekday number (Sunday being 0). | |
num_days_since_sunday = int(specified_date.strftime('%w')) | |
start_date = specified_date - timedelta(days=num_days_since_sunday) | |
end_date = start_date + timedelta(days=7) | |
return start_date, end_date | |
def _get_month_range(self, month_string=None): | |
if month_string: | |
# Because of DATE_PARSER_SETTINGS, providing '2017-12' here gets us the datetime for 2017-12-01. | |
start_date = parse(month_string, settings=DATE_PARSER_SETTINGS) | |
else: | |
# Start with midnight today, then replace the day-of-the-month with 1 to get the first day of this month. | |
start_date = parse('midnight today', settings=DATE_PARSER_SETTINGS).replace(day=1) | |
end_date = start_date + relativedelta(months=1) | |
return start_date, end_date | |
## Views | |
@path('') | |
def default_view(self, request): | |
if self.default_time_period == 'day': | |
start_date = localtime().replace(hour=0, minute=0, second=0, microsecond=0) | |
end_date = start_date + timedelta(days=1) | |
elif self.default_time_period == 'week': | |
# Get the date range for the current week. | |
start_date, end_date = self._get_week_range() | |
elif self.default_time_period == 'month': | |
# Get the date range for the current month. | |
start_date, end_date = self._get_month_range() | |
else: # self.default_time_period == 'future': | |
start_date = localtime() | |
end_date = None | |
context['events'] = self._build_date_filtered_queryset(site, start_date, end_date) | |
return self.render(request, context_overrides=context) | |
@path('day/', name='day') | |
@re_path(r'^day/(\d{4}-\d{1,2}-\d{1,2})/$', name='day') | |
def day_view(self, request, date_string=None): | |
""" | |
Displays all Events from a single, specified day, provided via a string like '2017-12-10'. | |
""" | |
if date_string: | |
start_date = parse(date_string, settings=DATE_PARSER_SETTINGS) | |
else: | |
start_date = localtime().replace(hour=0, minute=0, second=0, microsecond=0) | |
end_date = start_date + timedelta(days=1) | |
# Do not render this page if the user requested a day outside of the Calendar start and end range. | |
if not self._date_in_allowed_range(start_date): | |
raise Http404() | |
context['events'] = self._build_date_filtered_queryset(site, start_date, end_date) | |
return self.render(request, context_overrides=context) | |
@path('week/', name='week') | |
@re_path(r'^week/(\d{4}-\d{1,2}-\d{1,2})/$', name='week') | |
def week_view(self, request, date_string=None): | |
""" | |
Displays all Events from a single week. | |
Any date provided via a string like '2017-12-10' will display the week during which that date occurs, starting | |
on Sunday and ending on Saturday. | |
If no date is provided or the date_string isn't valid, the current week is displayed. | |
""" | |
specified_date = parse(date_string or 'midnight today', settings=DATE_PARSER_SETTINGS) | |
start_date, end_date = self._get_week_range(specified_date) | |
# Do not render this page if the user requested a day outside of the Calendar start and end range. | |
if not self._date_in_allowed_range(start_date): | |
raise Http404() | |
context['events'] = self._build_date_filtered_queryset(site, start_date, end_date) | |
return self.render(request, context_overrides=context) | |
@path('month/', name='month') | |
@re_path(r'^month/(\d{4}-\d{1,2})/$', name='month') | |
def month_view(self, request, month_string=None): | |
""" | |
Displays all Events in a single month. | |
Any month provided via a string like '2017-12' will display that month. | |
If no month is provided or the month is invalid, the current month is displayed. | |
""" | |
start_date, end_date = self._get_month_range(month_string) | |
# Do not render this page if the user requested a day outside of the Calendar start and end range. | |
if not self._date_in_allowed_range(start_date): | |
raise Http404() | |
context['events'] = self._build_date_filtered_queryset(site, start_date, end_date) | |
return self.render(request, context_overrides=context) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment