From d0b85f0dc8a90e7803ab0176bd15108a711df023 Mon Sep 17 00:00:00 2001 From: Erik Stein Date: Sun, 1 May 2022 20:55:13 +0200 Subject: [PATCH] Improved publication workflow. --- shared/utils/models/workflow.py | 62 ++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/shared/utils/models/workflow.py b/shared/utils/models/workflow.py index 8833d28..9cf9875 100644 --- a/shared/utils/models/workflow.py +++ b/shared/utils/models/workflow.py @@ -1,5 +1,7 @@ from django.conf import settings +from django.contrib import admin from django.db import models +from django.db.models import Q from django.utils import timezone from django.utils.translation import gettext_lazy as _ @@ -17,8 +19,7 @@ States: class WorkflowQuerySet(models.QuerySet): @classmethod - def exclude_inactive_filter(cls): - """Usage: qs.exclude(**self.exclude_inactive_filter())""" + def published_filter(cls): return { "is_published": True, "publication_datetime__lte": timezone.now(), @@ -29,7 +30,7 @@ class WorkflowQuerySet(models.QuerySet): return { "is_published": True, "publication_datetime__lte": timezone.now(), - "archiving_datetime__gte": timezone.now(), + "archiving_datetime__gt": timezone.now(), } @classmethod @@ -40,9 +41,14 @@ class WorkflowQuerySet(models.QuerySet): "archiving_datetime__lte": timezone.now(), } - def public(self): + def unpublished(self): + return self.exclude(**self.published_filter()) + + def published(self): # Active or archived - return self.exclude(**self.exclude_inactive_filter()) + return self.filter(**self.published_filter()) + + public = published def active(self): return self.filter(**self.active_filter()) @@ -65,9 +71,11 @@ class ManyToManyWorkflowQuerySet(WorkflowQuerySet): filter[f'{field.name}__{path}'] = value return filter - def public(self): + def published(self): # Active or archived - return self.exclude(**self._build_related_filters(self.exclude_inactive_filter())) + return self.exclude(**self._build_related_filters(self.published_filter())) + + public = published def active(self): return self.filter(**self._build_related_filters(self.active_filter())) @@ -94,7 +102,7 @@ class WorkflowMixin(models.Model): editable=False, on_delete=models.SET_NULL, related_name='+') - is_published = models.BooleanField(_("Publicly visible"), default=False) + is_published = models.BooleanField(_("Published"), default=False) publication_datetime = models.DateTimeField(_("Publication Date"), default=timezone.now) archiving_datetime = models.DateTimeField(_("Archiving Date"), default=timezone.datetime.max) @@ -107,17 +115,45 @@ class WorkflowMixin(models.Model): @property def worflow_status(self): now = timezone.now() - if not self.is_active or self.publication_datetime < now: - return 'inactive' + if not self.is_published or self.publication_datetime < now: + return 'unpublished' elif self.publication_datetime >= now and self.archiving_datetime < now: return 'active' else: return 'archived' -def display_is_active(obj): +def display_is_published(obj): return obj.is_published and obj.publication_datetime <= timezone.now() -display_is_active.boolean = True -display_is_active.short_description = _("Aktiv") +display_is_published.boolean = True +display_is_published.short_description = _("Aktiv") + + +class PublicationStateListFilter(admin.SimpleListFilter): + title = _("Published") + + # Parameter for the filter that will be used in the URL query. + parameter_name = 'workflow_state' + filter_dict = { + 'unpublished': 'unpublished', + 'public': 'public', + 'active': 'active', + 'archived': 'archived', + } + + def lookups(self, request, model_admin): + return ( + ('unpublished', _("Unpublished")), + ('public', _("Published (Active or Archived)")), + ('active', _("Active (published, not archived)")), + ('archived', _("Archived")), + ) + + def queryset(self, request, queryset): + if self.value(): + filter_method = self.filter_dict[self.value()] + return getattr(queryset, filter_method)() + else: + return queryset