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

Commit

Permalink
Make publishing filters work with generic Fluent models, re #32
Browse files Browse the repository at this point in the history
Make the `PublishingPublishedFilter` and `PublishingStatusFilter`
publishing status admin filters compatible with models that do not
provide the standard ICEKit publishing features (and DB fields) from
`PublishingModel`.

This change is necessary to make these filters usable on parent admin
pages that can include non-`PublishingModel` class, in particular the
Fluent Pages default parent page admin listing /admin/fluent_pages/page/

This change is a hack and requires iterating over the actual instances
of all models so it will be slow in cases where we cannot rely on
`PublishingModel` fields being present, but works around the problem
for now of filtering by two different publishing notions in the one
polymorphic parent admin page.
  • Loading branch information
jmurty committed Oct 10, 2016
1 parent d27b639 commit 8951966
Showing 1 changed file with 70 additions and 14 deletions.
84 changes: 70 additions & 14 deletions icekit/publishing/admin.py
Expand Up @@ -56,8 +56,30 @@ def queryset(self, request, queryset):
except TypeError:
return queryset

isnull = not value
return queryset.filter(publishing_linked__isnull=isnull)
show_published = bool(value)

# If admin is for a `PublishingModel` subclass use simple query...
if issubclass(queryset.model, PublishingModel):
return queryset.filter(
publishing_linked__isnull=not show_published)

# ...if admin is not for a `PublishingModel` subclass we must iterate
# over child model instances to keep compatibility with Fluent page
# admin and models not derived from `PublishingModel`.
pks_to_exclude = []
for item in queryset.get_real_instances():
if show_published:
if item.status == UrlNode.PUBLISHED:
continue # Published according to Fluent Pages' UrlNode
elif getattr(item, 'has_been_published', False):
continue # Published according to ICEKit Publishing
else:
if item.status == UrlNode.DRAFT \
and not getattr(item, 'has_been_published', False):
# Unpublished according to both Fluent and ICEKit
continue
pks_to_exclude.append(item.pk)
return queryset.exclude(pk__in=pks_to_exclude)


class PublishingStatusFilter(SimpleListFilter):
Expand Down Expand Up @@ -100,18 +122,52 @@ def lookups(self, request, model_admin):
return lookups

def queryset(self, request, queryset):
if self.value() == 'unpublished':
return queryset.filter(publishing_linked__isnull=True)
elif self.value() == 'published':
return queryset.filter(publishing_linked__isnull=False)
elif self.value() == 'out_of_date':
return queryset.filter(
publishing_modified_at__gt=F(
'publishing_linked__publishing_modified_at'))
elif self.value() == 'up_to_date':
return queryset.filter(
publishing_modified_at__lte=F(
'publishing_linked__publishing_modified_at'))
value = self.value()
if not value:
return queryset
# If admin is for a `PublishingModel` subclass use simple queries...
if issubclass(queryset.model, PublishingModel):
if value == 'unpublished':
return queryset.filter(publishing_linked__isnull=True)
elif value == 'published':
return queryset.filter(publishing_linked__isnull=False)
elif value == 'out_of_date':
return queryset.filter(
publishing_modified_at__gt=F(
'publishing_linked__publishing_modified_at'))
elif value == 'up_to_date':
return queryset.filter(
publishing_modified_at__lte=F(
'publishing_linked__publishing_modified_at'))
# ...if admin is not for a `PublishingModel` subclass we must iterate
# over child model instances to keep compatibility with Fluent page
# admin and models not derived from `PublishingModel`.
pks_to_exclude = []
for item in queryset.get_real_instances():
if value == 'unpublished':
if item.status == UrlNode.DRAFT \
and not getattr(item, 'has_been_published', False):
# Unpublished according to both Fluent and ICEKit
continue
elif value == 'published':
if item.status == UrlNode.PUBLISHED:
continue # Published according to Fluent Pages' UrlNode
elif getattr(item, 'has_been_published', False):
continue # Published according to ICEKit Publishing
elif value == 'out_of_date':
if (getattr(item, 'publishing_linked', None)
and item.publishing_modified_at
> item.publishing_linked.publishing_modified_at
):
continue # Published and outdated according to ICEKit
elif value == 'up_to_date':
if (getattr(item, 'publishing_linked', None)
and item.publishing_modified_at
<= item.publishing_linked.publishing_modified_at
):
continue # Published and up-to-date according to ICEKit
pks_to_exclude.append(item.pk)
return queryset.exclude(pk__in=pks_to_exclude)


class PublishingAdminForm(forms.ModelForm):
Expand Down

0 comments on commit 8951966

Please sign in to comment.