Implement Page.with_content_json and add to docs (fixes #5199)

pull/5380/head
Karl Hobley 2019-04-04 11:39:38 +01:00 zatwierdzone przez Andy Babic
rodzic 11af8123f7
commit d008cc7e21
2 zmienionych plików z 50 dodań i 24 usunięć

Wyświetl plik

@ -226,6 +226,8 @@ In addition to the model fields provided, ``Page`` has many properties and metho
Forms must be a subclass of :class:`~wagtail.admin.forms.WagtailAdminPageForm`.
See :ref:`custom_edit_handler_forms` for more information.
.. automethod:: with_content_json
.. _site-model-ref:
``Site``

Wyświetl plik

@ -1414,6 +1414,53 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
context['action_url'] = action_url
return TemplateResponse(request, self.password_required_template, context)
def with_content_json(self, content_json):
"""
Returns a new version of the page with field values updated to reflect changes
in the provided ``content_json`` (which usually comes from a previously-saved
page revision).
Certain field values are preserved in order to prevent errors if the returned
page is saved, such as ``id``, ``content_type`` and some tree-related values.
The following field values are also preserved, as they are considered to be
meaningful to the page as a whole, rather than to a specific revision:
* ``draft_title``
* ``live``
* ``has_unpublished_changes``
* ``owner``
* ``locked``
* ``latest_revision_created_at``
* ``first_published_at``
"""
obj = self.specific_class.from_json(content_json)
# These should definitely never change between revisions
obj.pk = self.pk
obj.content_type = self.content_type
# Override possibly-outdated tree parameter fields
obj.path = self.path
obj.depth = self.depth
obj.numchild = self.numchild
# Update url_path to reflect potential slug changes, but maintining the page's
# existing tree position
obj.set_url_path(self.get_parent())
# Ensure other values that are meaningful for the page as a whole (rather than
# to a specific revision) are preserved
obj.draft_title = self.draft_title
obj.live = self.live
obj.has_unpublished_changes = self.has_unpublished_changes
obj.owner = self.owner
obj.locked = self.locked
obj.latest_revision_created_at = self.latest_revision_created_at
obj.first_published_at = self.first_published_at
return obj
class Meta:
verbose_name = _('page')
verbose_name_plural = _('pages')
@ -1464,30 +1511,7 @@ class PageRevision(models.Model):
self.page.revisions.exclude(id=self.id).update(submitted_for_moderation=False)
def as_page_object(self):
obj = self.page.specific_class.from_json(self.content_json)
# Override the possibly-outdated tree parameter fields from this revision object
# with up-to-date values
obj.pk = self.page.pk
obj.path = self.page.path
obj.depth = self.page.depth
obj.numchild = self.page.numchild
# Populate url_path based on the revision's current slug and the parent page as determined
# by path
obj.set_url_path(self.page.get_parent())
# also copy over other properties which are meaningful for the page as a whole, not a
# specific revision of it
obj.draft_title = self.page.draft_title
obj.live = self.page.live
obj.has_unpublished_changes = self.page.has_unpublished_changes
obj.owner = self.page.owner
obj.locked = self.page.locked
obj.latest_revision_created_at = self.page.latest_revision_created_at
obj.first_published_at = self.page.first_published_at
return obj
return self.page.specific.with_content_json(self.content_json)
def approve_moderation(self):
if self.submitted_for_moderation: