From c0347aff22fe747494a049f53f7675f0ef858fb6 Mon Sep 17 00:00:00 2001 From: Erik Stein Date: Thu, 15 Nov 2018 10:07:22 +0100 Subject: [PATCH] Separated fields from methods in RuntimeMixin. --- shared/utils/models/events.py | 75 +++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/shared/utils/models/events.py b/shared/utils/models/events.py index 2482d06..5c34cc4 100644 --- a/shared/utils/models/events.py +++ b/shared/utils/models/events.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - import datetime from django.core.exceptions import ValidationError @@ -18,49 +15,37 @@ else: # FIXME Currently Python cannot handle BC dates -# Possibly solution: https://github.com/okfn/datautil/blob/master/datautil/date.py +# Possible solution: https://github.com/okfn/datautil/blob/master/datautil/date.py MIN_DATE = datetime.date.min MAX_DATE = datetime.date.max -class RuntimeMixin(models.Model): - """Allows a model to have partially defined from-/to-dates; +class RuntimeBehaviour: + """ + Allows a model to have partially defined from-/to-dates; at least one year value must be entered. """ - from_year_value = models.PositiveIntegerField(_("starting year"), null=True, blank=True) - from_month_value = models.PositiveIntegerField(_("starting month"), null=True, blank=True) - from_day_value = models.PositiveIntegerField(_("starting day"), null=True, blank=True) - _from_sort_date = models.DateField(_("from"), editable=False) - until_year_value = models.PositiveIntegerField(_("ending year"), null=True, blank=True) - until_month_value = models.PositiveIntegerField(_("ending month"), null=True, blank=True) - until_day_value = models.PositiveIntegerField(_("ending day"), null=True, blank=True) - _until_sort_date = models.DateField(_("until"), editable=False) - - runtime_text = TranslatableCharField(_("Zeitangabe Textform"), - max_length=200, null=True, blank=True, - help_text=_("Alternativer Text für die Laufzeitangabe")) + start_date_field_name = '_from_sort_date' + end_date_field_name = '_until_sort_date' allow_empty_runtime = False - class Meta: - abstract = True - def clean(self): if not self.allow_empty_runtime and not (self.from_year_value or self.until_year_value): raise ValidationError(_('Please enter either a from or an until date year.')) # Update from/sort date fields if self.from_year_value: - self._from_sort_date = datetime.date( - self.from_year_value, self.from_month_value or 1, self.from_day_value or 1) + setattr(self, self.start_date_field_name, datetime.date( + self.from_year_value, self.from_month_value or 1, self.from_day_value or 1)) else: - self._from_sort_date = MIN_DATE + setattr(self, self.start_date_field_name, MIN_DATE) if self.until_year_value: - self._until_sort_date = datetime.date( - self.until_year_value, self.until_month_value or 12, self.until_day_value or 31) + setattr(self, self.end_date_field_name, datetime.date( + self.until_year_value, self.until_month_value or 12, self.until_day_value or 31)) else: - self._until_sort_date = MAX_DATE + setattr(self, self.end_date_field_name, MAX_DATE) def save(self, *args, **kwargs): self.full_clean() @@ -68,20 +53,20 @@ class RuntimeMixin(models.Model): @property def from_date(self): - return self._from_sort_date + return getattr(self, self.start_date_field_name) @property def until_date(self): - return self._until_sort_date + return getattr(self, self.end_date_field_name) - # TODO Implement @fron_date.setter, @until_date.setter + # TODO ? Implement @from_date.setter, @until_date.setter def get_from_display(self): return self.runtime_text or format_partial_date( self.from_year_value, self.from_month_value, self.from_day_value) - get_from_display.admin_order_field = '_from_sort_date' + get_from_display.admin_order_field = start_date_field_name get_from_display.short_description = _("from") def get_until_display(self): @@ -92,18 +77,18 @@ class RuntimeMixin(models.Model): self.until_year_value, self.until_month_value, self.until_day_value) - get_until_display.admin_order_field = '_until_sort_date' + get_until_display.admin_order_field = end_date_field_name get_until_display.short_description = _("until") def get_runtime_display(self): # TODO Improve if not self.runtime_text and \ self.from_day_value and self.from_month_value: - return format_date_range(self._from_sort_date, self._until_sort_date) + return format_date_range(self.from_date, self.until_date) else: f = self.get_from_display() # Single point - if self._from_sort_date == self._until_sort_date: + if self.from_date == self.until_date: return f u = self.get_until_display() @@ -111,3 +96,25 @@ class RuntimeMixin(models.Model): return "{}–{}".format(f, u) else: return f or u + + +class RuntimeMixin(RuntimeBehaviour, models.Model): + from_year_value = models.PositiveIntegerField(_("starting year"), null=True, blank=True) + from_month_value = models.PositiveIntegerField(_("starting month"), null=True, blank=True) + from_day_value = models.PositiveIntegerField(_("starting day"), null=True, blank=True) + until_year_value = models.PositiveIntegerField(_("ending year"), null=True, blank=True) + until_month_value = models.PositiveIntegerField(_("ending month"), null=True, blank=True) + until_day_value = models.PositiveIntegerField(_("ending day"), null=True, blank=True) + _from_sort_date = models.DateField(_("from"), editable=False) + _until_sort_date = models.DateField(_("until"), editable=False) + + runtime_text = TranslatableCharField(_("Zeitangabe Textform"), + max_length=200, null=True, blank=True, + help_text=_("Alternativer Text für die Laufzeitangabe")) + + start_date_field_name = '_from_sort_date' + end_date_field_name = '_until_sort_date' + allow_empty_runtime = False + + class Meta: + abstract = True