kopia lustrzana https://github.com/wagtail/wagtail
Restore PageManager behaviour by setting it on an abstract superclass of Page
Django's standard behaviour is to preserve managers that are set on abstract superclasses, so this allows us to eliminate the metaclass hackery. Fixes #2933pull/2935/merge
rodzic
bfff095f8a
commit
7bc819640d
|
@ -14,6 +14,7 @@ Changelog
|
|||
|
||||
* Fix: Wagtail's middleware classes are now compatible with Django 1.10's new-style middleware (Karl Hobley)
|
||||
* Fix: The `Pages.can_create_at` method is now checked in the create page view (Mikalai Radchuk)
|
||||
* Fix: Fixed regression on Django 1.10.1 causing Page subclasses to fail to use PageManager (Matt Westcott)
|
||||
|
||||
|
||||
1.6 (15.08.2016)
|
||||
|
|
|
@ -15,3 +15,24 @@ Bug fixes
|
|||
|
||||
* Wagtail's middleware classes are now compatible with Django 1.10's `new-style middleware <https://docs.djangoproject.com/en/1.10/releases/1.10/#new-style-middleware>`_ (Karl Hobley)
|
||||
* The :meth:`~wagtail.wagtailcore.models.Page.can_create_at` method is now checked in the create page view (Mikalai Radchuk)
|
||||
* Fixed regression on Django 1.10.1 causing Page subclasses to fail to use PageManager (Matt Westcott)
|
||||
|
||||
|
||||
Upgrade considerations
|
||||
======================
|
||||
|
||||
Multi-level inheritance and custom managers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The inheritance rules for :ref:`custom_page_managers` have been updated to match Django's standard behaviour. In the vast majority of scenarios there will be no change. However, in the specific case where a page model with a custom ``objects`` manager is subclassed further, the subclass will be assigned a plain ``Manager`` instead of a ``PageManager``, and will now need to explicitly override this with a ``PageManager`` to function correctly:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class EventPage(Page):
|
||||
objects = EventManager()
|
||||
|
||||
|
||||
class SpecialEventPage(EventPage):
|
||||
# Previously SpecialEventPage.objects would be set to a PageManager automatically;
|
||||
# this now needs to be set explicitly
|
||||
objects = PageManager()
|
||||
|
|
|
@ -440,6 +440,8 @@ This is because ``Page`` enforces ordering QuerySets by path. Instead, you must
|
|||
|
||||
news_items = NewsItemPage.objects.live().order_by('-publication_date')
|
||||
|
||||
.. _custom_page_managers:
|
||||
|
||||
Custom Page managers
|
||||
--------------------
|
||||
|
||||
|
|
|
@ -261,14 +261,6 @@ class PageBase(models.base.ModelBase):
|
|||
# don't proceed with all this page type registration stuff
|
||||
return
|
||||
|
||||
# Override the default `objects` attribute with a `PageManager`.
|
||||
# Managers are not inherited by MTI child models, so `Page` subclasses
|
||||
# will get a plain `Manager` instead of a `PageManager`.
|
||||
# If the developer has set their own custom `Manager` subclass, do not
|
||||
# clobber it.
|
||||
if not cls._meta.abstract and type(cls.objects) is models.Manager:
|
||||
PageManager().contribute_to_class(cls, 'objects')
|
||||
|
||||
if 'template' not in dct:
|
||||
# Define a default template path derived from the app name and model name
|
||||
cls.template = "%s/%s.html" % (cls._meta.app_label, camelcase_to_underscore(name))
|
||||
|
@ -289,8 +281,21 @@ class PageBase(models.base.ModelBase):
|
|||
PAGE_MODEL_CLASSES.append(cls)
|
||||
|
||||
|
||||
class AbstractPage(MP_Node):
|
||||
"""
|
||||
Abstract superclass for Page. According to Django's inheritance rules, managers set on
|
||||
abstract models are inherited by subclasses, but managers set on concrete models that are extended
|
||||
via multi-table inheritance are not. We therefore need to attach PageManager to an abstract
|
||||
superclass to ensure that it is retained by subclasses of Page.
|
||||
"""
|
||||
objects = PageManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Page(six.with_metaclass(PageBase, MP_Node, index.Indexed, ClusterableModel)):
|
||||
class Page(six.with_metaclass(PageBase, AbstractPage, index.Indexed, ClusterableModel)):
|
||||
title = models.CharField(
|
||||
verbose_name=_('title'),
|
||||
max_length=255,
|
||||
|
@ -391,8 +396,6 @@ class Page(six.with_metaclass(PageBase, MP_Node, index.Indexed, ClusterableModel
|
|||
# Do not allow plain Page instances to be created through the Wagtail admin
|
||||
is_creatable = False
|
||||
|
||||
objects = PageManager()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Page, self).__init__(*args, **kwargs)
|
||||
if not self.id and not self.content_type_id:
|
||||
|
|
Ładowanie…
Reference in New Issue