From 62de2fb9604f9a43f8458d61a401096a47528a32 Mon Sep 17 00:00:00 2001 From: James Murty Date: Wed, 22 Feb 2017 12:08:40 +1100 Subject: [PATCH] Add richer filters for Event content listing plugin - filter events shown in listing by primary/secondary `EventType` - filter events shown in listing to those with occurrences within given start/end datetimes - filter events shown in listing to those with occurrences that end after N days ago, and/or start before N days hence. --- .../event_content_listing/abstract_models.py | 59 ++++++++++++++++++- .../migrations/0002_auto_20170222_1136.py | 40 +++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 icekit_events/plugins/event_content_listing/migrations/0002_auto_20170222_1136.py diff --git a/icekit_events/plugins/event_content_listing/abstract_models.py b/icekit_events/plugins/event_content_listing/abstract_models.py index 4c73306..2a0b777 100644 --- a/icekit_events/plugins/event_content_listing/abstract_models.py +++ b/icekit_events/plugins/event_content_listing/abstract_models.py @@ -1,6 +1,13 @@ +from datetime import timedelta + +from django.db import models +from django.db.models import Q from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ +from timezone import timezone as djtz # django-timezone + +from icekit_events.models import EventType from icekit.plugins.content_listing.abstract_models import \ AbstractContentListingItem @@ -10,6 +17,34 @@ class AbstractEventContentListingItem(AbstractContentListingItem): """ An embedded listing of event content items. """ + limit_to_types = models.ManyToManyField( + EventType, + help_text="Leave empty to show all events.", + blank=True, + db_table="ik_event_listing_types", + ) + from_date = models.DateTimeField( + blank=True, null=True, + help_text="Only show events with occurrences that end after this" + " date and time.", + ) + to_date = models.DateTimeField( + blank=True, null=True, + help_text="Only show events with occurrences that start before this" + " date and time.", + ) + from_days_ago = models.IntegerField( + blank=True, null=True, + help_text="Only show events with occurrences after this number of" + " days into the past. Set this to zero to show only events" + " with future occurrences.", + ) + to_days_ahead = models.IntegerField( + blank=True, null=True, + help_text="Only show events with occurrences before this number of" + " days into the future. Set this to zero to show only events" + " with past occurrences.", + ) class Meta: abstract = True @@ -19,4 +54,26 @@ def __str__(self): return 'Event Content Listing of %s' % self.content_type def get_items(self): - return super(AbstractEventContentListingItem, self).get_items() + qs = super(AbstractEventContentListingItem, self).get_items( + apply_limit=False) + if self.limit_to_types.count(): + types = self.limit_to_types.all() + qs = qs.filter( + Q(primary_type__in=types) | + Q(secondary_types__in=types) + ) + # Apply `from_date` and `to_date` limits + qs = qs.overlapping(self.from_date, self.to_date) + # Apply `from_days_ago` and `to_days_ahead` limits + today = djtz.now().date() + from_date = to_date = None + if self.from_days_ago is not None: + from_date = today - timedelta(days=self.from_days_ago) + if self.to_days_ahead is not None: + to_date = today + timedelta(days=self.to_days_ahead) + qs = qs.overlapping(from_date, to_date) + # Apply a sensible default ordering + qs = qs.order_by_first_occurrence() + if self.limit: + qs = qs[:self.limit] + return qs diff --git a/icekit_events/plugins/event_content_listing/migrations/0002_auto_20170222_1136.py b/icekit_events/plugins/event_content_listing/migrations/0002_auto_20170222_1136.py new file mode 100644 index 0000000..74f8baf --- /dev/null +++ b/icekit_events/plugins/event_content_listing/migrations/0002_auto_20170222_1136.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('icekit_events', '0016_auto_20161208_0030'), + ('ik_event_listing', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='eventcontentlistingitem', + name='from_date', + field=models.DateTimeField(help_text=b'Only show events with occurrences that end after this date and time.', null=True, blank=True), + ), + migrations.AddField( + model_name='eventcontentlistingitem', + name='from_days_ago', + field=models.IntegerField(help_text=b'Only show events with occurrences after this number of days into the past. Set this to zero to show only events with future occurrences.', null=True, blank=True), + ), + migrations.AddField( + model_name='eventcontentlistingitem', + name='limit_to_types', + field=models.ManyToManyField(help_text=b'Leave empty to show all events.', to='icekit_events.EventType', db_table=b'ik_event_listing_types', blank=True), + ), + migrations.AddField( + model_name='eventcontentlistingitem', + name='to_date', + field=models.DateTimeField(help_text=b'Only show events with occurrences that start before this date and time.', null=True, blank=True), + ), + migrations.AddField( + model_name='eventcontentlistingitem', + name='to_days_ahead', + field=models.IntegerField(help_text=b'Only show events with occurrences before this number of days into the future. Set this to zero to show only events with past occurrences.', null=True, blank=True), + ), + ]