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

Commit a025303

Browse files
committed
Improve ICEKit Publishing support for Polymorphic models
- add supporting class helpers for working with plain polymorphic models that are not also `UrlNode`s or `FluentContentsPage`s: `PublishingPolymorphicQuerySet`, `PublishingPolymorphicManager` - fix some assumptions about model admins that don't hold for polymorphic parent and basic admins, such as `change_form_template` isn't always available - don't perform placeholder cloning or patching for models that are not `FluentContentsPage`s
1 parent 03c3da4 commit a025303

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

icekit/publishing/admin.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,11 @@ def __init__(self, model, admin_site):
297297
self.admin_site.name,
298298
self.get_url_name_prefix(model), )
299299

300-
self.non_publishing_change_form_template = \
301-
self.find_first_available_template(self.change_form_template)
300+
# Some admins are missing a `change_form_template` such as
301+
# PolymorphicParentModelAdmin
302+
if self.change_form_template:
303+
self.non_publishing_change_form_template = \
304+
self.find_first_available_template(self.change_form_template)
302305

303306
def find_first_available_template(self, template_name_list):
304307
"""
@@ -518,13 +521,13 @@ def render_change_form(self, request, context, add=False, change=False,
518521
# Override this admin's change form template to point to the publishing
519522
# admin page template, but only for long enough to render the change
520523
# form.
521-
if isinstance(self, DefaultPageChildAdmin) \
524+
if hasattr(type(self).change_form_template, '__get__') \
522525
and isinstance(self.change_form_template, (list, tuple)):
523-
# Special handling for `DefaultPageChildAdmin` subclases with
524-
# multiple templates, a feature of FluentPages that is as confusing
525-
# as it is helpful. In this case, find the best available template
526-
# preferring publishing-specific templates and apply it via
527-
# a context variable that should be respected by Fluent's base
526+
# Special handling for class that provide multiple templates via,
527+
# a `change_form_template` get-only property instead of the usual
528+
# plain class attribute. In this case, find the best available
529+
# template preferring publishing-specific templates and apply it
530+
# via a context variable that should be respected by Fluent's base
528531
# templates, which we are most likely using at this point.
529532
opts = self.model._meta
530533
app_label = opts.app_label

icekit/publishing/apps.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
from fluent_pages.models import UrlNode
77
from fluent_pages.models.managers import UrlNodeQuerySet
88

9+
from polymorphic.polymorphic_model import PolymorphicModel
10+
911
from mptt.models import MPTTModel
1012

1113
from . import monkey_patches
12-
from .managers import PublishingQuerySet, PublishingUrlNodeManager, \
13-
UrlNodeQuerySetWithPublishingFeatures, DraftItemBoobyTrap, \
14-
_queryset_iterator
14+
from .managers import PublishingQuerySet, PublishingPolymorphicManager, \
15+
PublishingUrlNodeManager, UrlNodeQuerySetWithPublishingFeatures, \
16+
DraftItemBoobyTrap, _queryset_iterator
1517
from .models import PublishingModel
1618
from .middleware import is_draft_request_context, \
1719
is_publishing_middleware_active
@@ -217,6 +219,13 @@ def _filter_candidates_by_published_status(candidates, model, path):
217219
if not issubclass(model, PublishingModel):
218220
continue
219221

222+
if issubclass(model, PolymorphicModel):
223+
224+
PublishingPolymorphicManager().contribute_to_class(
225+
model, 'objects')
226+
PublishingPolymorphicManager().contribute_to_class(
227+
model, '_default_manager')
228+
220229
if issubclass(model, UrlNode):
221230

222231
PublishingUrlNodeManager().contribute_to_class(

icekit/publishing/managers.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
from django.db.models.query_utils import Q
44
from django.utils.timezone import now
55

6+
from polymorphic.manager import PolymorphicManager
7+
from polymorphic.query import PolymorphicQuerySet
8+
69
from fluent_pages.models.managers import UrlNodeQuerySet, UrlNodeManager
710
from fluent_pages.models.db import UrlNode
811

@@ -318,6 +321,10 @@ def only(self, *args, **kwargs):
318321
.only(*field_names, **kwargs)
319322

320323

324+
class PublishingPolymorphicQuerySet(PublishingQuerySet, PolymorphicQuerySet):
325+
pass
326+
327+
321328
class PublishingUrlNodeQuerySet(PublishingQuerySet, UrlNodeQuerySet):
322329
"""
323330
Publishing queryset with customisations for UrlNode support.
@@ -407,6 +414,15 @@ def get_queryset(self):
407414
return PublishingQuerySet(self.model, using=self._db).all()
408415

409416

417+
class PublishingPolymorphicManager(PolymorphicManager, PublishingManager):
418+
"""
419+
Publishing manager with polymorphic support and customisations.
420+
"""
421+
queryset_class = PublishingPolymorphicQuerySet
422+
# Tell Django that related fields also need to use this manager:
423+
use_for_related_fields = True
424+
425+
410426
class PublishingUrlNodeManager(UrlNodeManager, PublishingManager):
411427
"""
412428
Publishing manager with UrlNode support and customisations.

icekit/publishing/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,8 @@ def clone(src, dst):
446446

447447
@assert_draft
448448
def patch_placeholders(self):
449+
if not isinstance(self, FluentContentsPage):
450+
return
449451
published_obj = self.publishing_linked
450452

451453
for draft_placeholder, published_placeholder in zip(
@@ -492,6 +494,8 @@ def clone_placeholder(self, dst_obj):
492494
are to be related.
493495
:return: None
494496
"""
497+
if not isinstance(self, FluentContentsPage):
498+
return
495499
for src_placeholder in Placeholder.objects.parent(self):
496500
dst_placeholder = Placeholder.objects.create_for_object(
497501
dst_obj,

0 commit comments

Comments
 (0)