Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
#288 Potentially reduce tight coupling of events models
Browse files Browse the repository at this point in the history
Make changes to events models that *might* help
make it feasible to swap out the fundamental model
types like `EventType` and `Occurrence` with
custom versions in a project.

This is just a first step and the feasibility
of actually making swappable models needs to be
tested, proved, and documented.

- use string references for `ForeignKey`
  relationships so the actual implementation can
  be overridden with custom versions in a project
  (perhaps)
- create abstract base classes for `EventType`,
  `EventRepeatsGenerator`, `Occurrence` with the
  core implementation, with the idea these models
  can be subclassed and customised in a project.
  • Loading branch information
jmurty committed Aug 29, 2017
1 parent 8743fc3 commit 26bdaff
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions icekit_events/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ class RecurrenceRule(AbstractBaseModel):
def __str__(self):
return self.description

class EventType(PluralTitleSlugMixin):

class AbstractEventType(PluralTitleSlugMixin):
is_public = models.BooleanField(
"Show to public?",
default=True,
Expand All @@ -142,12 +143,16 @@ def swatch(self, color_only=False):
""").render(Context({'o': self, 'color_only': color_only}))

class Meta:
abstract = True
# changing the verbose name rather than renaming because model rename
# migrations are sloooooow
verbose_name = "Event category"
verbose_name_plural = "Event categories"


class EventType(AbstractEventType):
pass


@encoding.python_2_unicode_compatible
class EventBase(PolymorphicModel, AbstractBaseModel, ICEkitContentsMixin,
Expand All @@ -168,7 +173,8 @@ class EventBase(PolymorphicModel, AbstractBaseModel, ICEkitContentsMixin,
objects = EventManager()

primary_type = models.ForeignKey(
EventType, blank=True, null=True,
'icekit_events.EventType',
blank=True, null=True,
verbose_name="Primary category",
help_text="The primary category of this event: Talk, workshop, etc. Only "
"'public' event categories can be primary.",
Expand Down Expand Up @@ -614,7 +620,7 @@ class GeneratorException(Exception):


@encoding.python_2_unicode_compatible
class EventRepeatsGenerator(AbstractBaseModel):
class AbstractEventRepeatsGenerator(AbstractBaseModel):
"""
A model storing the information and features required to generate a set
of repeating datetimes for a given repeat rule.
Expand All @@ -633,7 +639,7 @@ class EventRepeatsGenerator(AbstractBaseModel):
explicitly is most likely the easiest way to ensure this.
"""
event = models.ForeignKey(
EventBase,
'icekit_events.EventBase',
db_index=True,
editable=False,
related_name='repeat_generators',
Expand Down Expand Up @@ -661,6 +667,7 @@ class EventRepeatsGenerator(AbstractBaseModel):
)

class Meta:
abstract = True
ordering = ['pk'] # Order by PK, essentially in creation order

def __str__(self):
Expand Down Expand Up @@ -782,7 +789,7 @@ def save(self, *args, **kwargs):
self.end = zero_datetime(self.end) \
+ timedelta(days=1, microseconds=-1)

super(EventRepeatsGenerator, self).save(*args, **kwargs)
super(AbstractEventRepeatsGenerator, self).save(*args, **kwargs)

@property
def duration(self):
Expand All @@ -792,23 +799,27 @@ def duration(self):
return self.end - self.start


class EventRepeatsGenerator(AbstractEventRepeatsGenerator):
pass


@encoding.python_2_unicode_compatible
class Occurrence(AbstractBaseModel):
class AbstractOccurrence(AbstractBaseModel):
"""
A specific occurrence of an Event with start and end date times, and
a reference back to the owner event that contains all the other data.
"""
objects = OccurrenceManager()

event = models.ForeignKey(
EventBase,
'icekit_events.EventBase',
db_index=True,
editable=False,
related_name='occurrences',
on_delete=models.CASCADE
)
generator = models.ForeignKey(
EventRepeatsGenerator,
'icekit_events.EventRepeatsGenerator',
blank=True, null=True,
on_delete=models.SET_NULL
)
Expand Down Expand Up @@ -850,6 +861,7 @@ class Occurrence(AbstractBaseModel):
blank=True, null=True, editable=False)

class Meta:
abstract = True
ordering = ['start', '-is_all_day', 'event', 'pk']

def time_range_string(self):
Expand Down Expand Up @@ -911,7 +923,7 @@ def save(self, *args, **kwargs):
self.original_start = self.start
if not self.original_end:
self.original_end = self.end
super(Occurrence, self).save(*args, **kwargs)
super(AbstractOccurrence, self).save(*args, **kwargs)

# TODO Return __str__ as title for now, improve it later
def title(self):
Expand All @@ -927,6 +939,10 @@ def get_absolute_url(self):
return self.event.get_occurrence_url(self)


class Occurrence(AbstractOccurrence):
pass


def get_occurrence_times_for_event(event):
"""
Return a tuple with two sets containing the (start, end) *naive* datetimes
Expand Down

0 comments on commit 26bdaff

Please sign in to comment.