kopia lustrzana https://github.com/wagtail/wagtail
Merge branch 'page-publish-refactor' of https://github.com/kaedroho/wagtail into kaedroho-page-publish-refactor
Conflicts: wagtail/wagtailcore/models.pypull/566/head
commit
c62d037c11
|
@ -18,7 +18,6 @@ from wagtail.wagtailadmin import tasks, signals
|
||||||
|
|
||||||
from wagtail.wagtailcore import hooks
|
from wagtail.wagtailcore import hooks
|
||||||
from wagtail.wagtailcore.models import Page, PageRevision, get_navigation_menu_items
|
from wagtail.wagtailcore.models import Page, PageRevision, get_navigation_menu_items
|
||||||
from wagtail.wagtailcore.signals import page_published, page_unpublished
|
|
||||||
|
|
||||||
|
|
||||||
@permission_required('wagtailadmin.access_admin')
|
@permission_required('wagtailadmin.access_admin')
|
||||||
|
@ -181,39 +180,31 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
|
||||||
form.clean = clean
|
form.clean = clean
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
page = form.save(commit=False) # don't save yet, as we need treebeard to assign tree params
|
page = form.save(commit=False)
|
||||||
|
|
||||||
is_publishing = bool(request.POST.get('action-publish')) and parent_page_perms.can_publish_subpage()
|
is_publishing = bool(request.POST.get('action-publish')) and parent_page_perms.can_publish_subpage()
|
||||||
is_submitting = bool(request.POST.get('action-submit'))
|
is_submitting = bool(request.POST.get('action-submit'))
|
||||||
go_live_at = form.cleaned_data.get('go_live_at')
|
|
||||||
future_go_live = go_live_at and go_live_at > timezone.now()
|
|
||||||
approved_go_live_at = None
|
|
||||||
|
|
||||||
if is_publishing:
|
# Set live to False and has_unpublished_changes to True if we are not publishing
|
||||||
page.has_unpublished_changes = False
|
if not is_publishing:
|
||||||
page.expired = False
|
|
||||||
if future_go_live:
|
|
||||||
page.live = False
|
|
||||||
# Set approved_go_live_at only if is publishing
|
|
||||||
# and the future_go_live is actually in future
|
|
||||||
approved_go_live_at = go_live_at
|
|
||||||
else:
|
|
||||||
page.live = True
|
|
||||||
else:
|
|
||||||
page.live = False
|
page.live = False
|
||||||
page.has_unpublished_changes = True
|
page.has_unpublished_changes = True
|
||||||
|
|
||||||
parent_page.add_child(instance=page) # assign tree parameters - will cause page to be saved
|
# Save page
|
||||||
|
parent_page.add_child(instance=page)
|
||||||
|
|
||||||
# Pass approved_go_live_at to save_revision
|
# Save revision
|
||||||
page.save_revision(
|
revision = page.save_revision(
|
||||||
user=request.user,
|
user=request.user,
|
||||||
submitted_for_moderation=is_submitting,
|
submitted_for_moderation=is_submitting,
|
||||||
approved_go_live_at=approved_go_live_at
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Publish
|
||||||
|
if is_publishing:
|
||||||
|
revision.publish()
|
||||||
|
|
||||||
|
# Notifications
|
||||||
if is_publishing:
|
if is_publishing:
|
||||||
page_published.send(sender=page_class, instance=page)
|
|
||||||
messages.success(request, _("Page '{0}' published.").format(page.title))
|
messages.success(request, _("Page '{0}' published.").format(page.title))
|
||||||
elif is_submitting:
|
elif is_submitting:
|
||||||
messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title))
|
messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title))
|
||||||
|
@ -298,54 +289,32 @@ def edit(request, page_id):
|
||||||
form.clean = clean
|
form.clean = clean
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
|
page = form.save(commit=False)
|
||||||
|
|
||||||
is_publishing = bool(request.POST.get('action-publish')) and page_perms.can_publish()
|
is_publishing = bool(request.POST.get('action-publish')) and page_perms.can_publish()
|
||||||
is_submitting = bool(request.POST.get('action-submit'))
|
is_submitting = bool(request.POST.get('action-submit'))
|
||||||
go_live_at = form.cleaned_data.get('go_live_at')
|
|
||||||
future_go_live = go_live_at and go_live_at > timezone.now()
|
|
||||||
approved_go_live_at = None
|
|
||||||
|
|
||||||
|
# Save revision
|
||||||
|
revision = page.save_revision(
|
||||||
|
user=request.user,
|
||||||
|
submitted_for_moderation=is_submitting,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Publish
|
||||||
if is_publishing:
|
if is_publishing:
|
||||||
page.has_unpublished_changes = False
|
revision.publish()
|
||||||
page.expired = False
|
|
||||||
if future_go_live:
|
|
||||||
page.live = False
|
|
||||||
# Set approved_go_live_at only if publishing
|
|
||||||
approved_go_live_at = go_live_at
|
|
||||||
else:
|
|
||||||
page.live = True
|
|
||||||
|
|
||||||
# We need save the page this way to workaround a bug
|
|
||||||
# in django-modelcluster causing m2m fields to not
|
|
||||||
# be committed to the database. See github issue #192
|
|
||||||
form.save(commit=False)
|
|
||||||
page.save()
|
|
||||||
|
|
||||||
# Clear approved_go_live_at for older revisions
|
|
||||||
page.revisions.update(
|
|
||||||
submitted_for_moderation=False,
|
|
||||||
approved_go_live_at=None,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# not publishing the page
|
# Set has_unpublished_changes flag
|
||||||
if page.live:
|
if page.live:
|
||||||
# To avoid overwriting the live version, we only save the page
|
# To avoid overwriting the live version, we only save the page
|
||||||
# to the revisions table
|
# to the revisions table
|
||||||
form.save(commit=False)
|
|
||||||
Page.objects.filter(id=page.id).update(has_unpublished_changes=True)
|
Page.objects.filter(id=page.id).update(has_unpublished_changes=True)
|
||||||
else:
|
else:
|
||||||
page.has_unpublished_changes = True
|
page.has_unpublished_changes = True
|
||||||
form.save(commit=False)
|
|
||||||
page.save()
|
page.save()
|
||||||
|
|
||||||
|
# Notifications
|
||||||
page.save_revision(
|
|
||||||
user=request.user,
|
|
||||||
submitted_for_moderation=is_submitting,
|
|
||||||
approved_go_live_at=approved_go_live_at
|
|
||||||
)
|
|
||||||
|
|
||||||
if is_publishing:
|
if is_publishing:
|
||||||
page_published.send(sender=page.__class__, instance=page)
|
|
||||||
messages.success(request, _("Page '{0}' published.").format(page.title))
|
messages.success(request, _("Page '{0}' published.").format(page.title))
|
||||||
elif is_submitting:
|
elif is_submitting:
|
||||||
messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title))
|
messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title))
|
||||||
|
@ -391,19 +360,9 @@ def delete(request, page_id):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
if request.POST:
|
if request.POST:
|
||||||
if page.live:
|
|
||||||
# fetch params to pass to the page_unpublished_signal, before the
|
|
||||||
# deletion happens
|
|
||||||
specific_class = page.specific_class
|
|
||||||
specific_page = page.specific
|
|
||||||
|
|
||||||
parent_id = page.get_parent().id
|
parent_id = page.get_parent().id
|
||||||
page.delete()
|
page.delete()
|
||||||
|
|
||||||
# If the page is live, send the unpublished signal
|
|
||||||
if page.live:
|
|
||||||
page_unpublished.send(sender=specific_class, instance=specific_page)
|
|
||||||
|
|
||||||
messages.success(request, _("Page '{0}' deleted.").format(page.title))
|
messages.success(request, _("Page '{0}' deleted.").format(page.title))
|
||||||
|
|
||||||
for fn in hooks.get_hooks('after_delete_page'):
|
for fn in hooks.get_hooks('after_delete_page'):
|
||||||
|
@ -538,18 +497,11 @@ def unpublish(request, page_id):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
if request.POST:
|
if request.POST:
|
||||||
parent_id = page.get_parent().id
|
page.unpublish()
|
||||||
page.live = False
|
|
||||||
page.save()
|
|
||||||
|
|
||||||
# Since page is unpublished clear the approved_go_live_at of all revisions
|
|
||||||
page.revisions.update(approved_go_live_at=None)
|
|
||||||
|
|
||||||
page_unpublished.send(sender=page.specific_class, instance=page.specific)
|
|
||||||
|
|
||||||
messages.success(request, _("Page '{0}' unpublished.").format(page.title))
|
messages.success(request, _("Page '{0}' unpublished.").format(page.title))
|
||||||
|
|
||||||
return redirect('wagtailadmin_explore', parent_id)
|
return redirect('wagtailadmin_explore', page.get_parent().id)
|
||||||
|
|
||||||
return render(request, 'wagtailadmin/pages/confirm_unpublish.html', {
|
return render(request, 'wagtailadmin/pages/confirm_unpublish.html', {
|
||||||
'page': page,
|
'page': page,
|
||||||
|
@ -761,8 +713,7 @@ def approve_moderation(request, revision_id):
|
||||||
return redirect('wagtailadmin_home')
|
return redirect('wagtailadmin_home')
|
||||||
|
|
||||||
if request.POST:
|
if request.POST:
|
||||||
revision.publish()
|
revision.approve_moderation()
|
||||||
page_published.send(sender=revision.page.__class__, instance=revision.page.specific)
|
|
||||||
messages.success(request, _("Page '{0}' published.").format(revision.page.title))
|
messages.success(request, _("Page '{0}' published.").format(revision.page.title))
|
||||||
tasks.send_notification.delay(revision.id, 'approved', request.user.id)
|
tasks.send_notification.delay(revision.id, 'approved', request.user.id)
|
||||||
|
|
||||||
|
@ -780,8 +731,7 @@ def reject_moderation(request, revision_id):
|
||||||
return redirect('wagtailadmin_home')
|
return redirect('wagtailadmin_home')
|
||||||
|
|
||||||
if request.POST:
|
if request.POST:
|
||||||
revision.submitted_for_moderation = False
|
revision.reject_moderation()
|
||||||
revision.save(update_fields=['submitted_for_moderation'])
|
|
||||||
messages.success(request, _("Page '{0}' rejected for publication.").format(revision.page.title))
|
messages.success(request, _("Page '{0}' rejected for publication.").format(revision.page.title))
|
||||||
tasks.send_notification.delay(revision.id, 'rejected', request.user.id)
|
tasks.send_notification.delay(revision.id, 'rejected', request.user.id)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ from django.core.management.base import BaseCommand
|
||||||
from django.utils import dateparse, timezone
|
from django.utils import dateparse, timezone
|
||||||
|
|
||||||
from wagtail.wagtailcore.models import Page, PageRevision
|
from wagtail.wagtailcore.models import Page, PageRevision
|
||||||
from wagtail.wagtailcore.signals import page_published, page_unpublished
|
|
||||||
|
|
||||||
|
|
||||||
def revision_date_expired(r):
|
def revision_date_expired(r):
|
||||||
|
@ -56,15 +55,11 @@ class Command(BaseCommand):
|
||||||
else:
|
else:
|
||||||
print("No expired pages to be deactivated found.")
|
print("No expired pages to be deactivated found.")
|
||||||
else:
|
else:
|
||||||
# need to get the list of expired pages before the update,
|
# Unpublish the expired pages
|
||||||
# so that we can fire the page_unpublished signal on them afterwards
|
# Cast to list to make sure the query is fully evaluated
|
||||||
expired_pages_list = list(expired_pages)
|
# before unpublishing anything
|
||||||
|
for page in list(expired_pages):
|
||||||
expired_pages.update(expired=True, live=False)
|
page.unpublish(set_expired=True)
|
||||||
|
|
||||||
# Fire page_unpublished signal for all expired pages
|
|
||||||
for page in expired_pages_list:
|
|
||||||
page_unpublished.send(sender=page.specific_class, instance=page.specific)
|
|
||||||
|
|
||||||
# 2. get all page revisions for moderation that have been expired
|
# 2. get all page revisions for moderation that have been expired
|
||||||
expired_revs = [
|
expired_revs = [
|
||||||
|
@ -118,6 +113,3 @@ class Command(BaseCommand):
|
||||||
# just run publish for the revision -- since the approved go
|
# just run publish for the revision -- since the approved go
|
||||||
# live datetime is before now it will make the page live
|
# live datetime is before now it will make the page live
|
||||||
rp.publish()
|
rp.publish()
|
||||||
|
|
||||||
# Fire page_published signal
|
|
||||||
page_published.send(sender=rp.page.specific_class, instance=rp.page.specific)
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ from modelcluster.models import ClusterableModel, get_all_child_relations
|
||||||
|
|
||||||
from django.db import models, connection, transaction
|
from django.db import models, connection, transaction
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.db.models.signals import pre_delete
|
||||||
|
from django.dispatch.dispatcher import receiver
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.handlers.wsgi import WSGIRequest
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
|
@ -29,6 +31,7 @@ from treebeard.mp_tree import MP_Node
|
||||||
from wagtail.wagtailcore.utils import camelcase_to_underscore, resolve_model_string
|
from wagtail.wagtailcore.utils import camelcase_to_underscore, resolve_model_string
|
||||||
from wagtail.wagtailcore.query import PageQuerySet
|
from wagtail.wagtailcore.query import PageQuerySet
|
||||||
from wagtail.wagtailcore.url_routing import RouteResult
|
from wagtail.wagtailcore.url_routing import RouteResult
|
||||||
|
from wagtail.wagtailcore.signals import page_published, page_unpublished
|
||||||
|
|
||||||
from wagtail.wagtailsearch import index
|
from wagtail.wagtailsearch import index
|
||||||
from wagtail.wagtailsearch.backends import get_search_backend
|
from wagtail.wagtailsearch.backends import get_search_backend
|
||||||
|
@ -422,6 +425,20 @@ class Page(six.with_metaclass(PageBase, MP_Node, ClusterableModel, index.Indexed
|
||||||
else:
|
else:
|
||||||
return self.specific
|
return self.specific
|
||||||
|
|
||||||
|
def unpublish(self, set_expired=False, commit=True):
|
||||||
|
if self.live:
|
||||||
|
self.live = False
|
||||||
|
|
||||||
|
if set_expired:
|
||||||
|
self.expired = True
|
||||||
|
|
||||||
|
if commit:
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
page_unpublished.send(sender=self.specific_class, instance=self.specific)
|
||||||
|
|
||||||
|
self.revisions.update(approved_go_live_at=None)
|
||||||
|
|
||||||
def get_context(self, request, *args, **kwargs):
|
def get_context(self, request, *args, **kwargs):
|
||||||
return {
|
return {
|
||||||
'self': self,
|
'self': self,
|
||||||
|
@ -863,6 +880,14 @@ def get_navigation_menu_items():
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(pre_delete, sender=Page)
|
||||||
|
def unpublish_page_before_delete(sender, instance, **kwargs):
|
||||||
|
# Make sure pages are unpublished before deleting
|
||||||
|
if instance.live:
|
||||||
|
# Don't bother to save, this page is just about to be deleted!
|
||||||
|
instance.unpublish(commit=False)
|
||||||
|
|
||||||
|
|
||||||
class Orderable(models.Model):
|
class Orderable(models.Model):
|
||||||
sort_order = models.IntegerField(null=True, blank=True, editable=False)
|
sort_order = models.IntegerField(null=True, blank=True, editable=False)
|
||||||
sort_order_field = 'sort_order'
|
sort_order_field = 'sort_order'
|
||||||
|
@ -916,6 +941,15 @@ class PageRevision(models.Model):
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
def approve_moderation(self):
|
||||||
|
if self.submitted_for_moderation:
|
||||||
|
self.publish()
|
||||||
|
|
||||||
|
def reject_moderation(self):
|
||||||
|
if self.submitted_for_moderation:
|
||||||
|
self.submitted_for_moderation = False
|
||||||
|
self.save(update_fields=['submitted_for_moderation'])
|
||||||
|
|
||||||
def publish(self):
|
def publish(self):
|
||||||
page = self.as_page_object()
|
page = self.as_page_object()
|
||||||
if page.go_live_at and page.go_live_at > timezone.now():
|
if page.go_live_at and page.go_live_at > timezone.now():
|
||||||
|
@ -935,6 +969,9 @@ class PageRevision(models.Model):
|
||||||
self.submitted_for_moderation = False
|
self.submitted_for_moderation = False
|
||||||
page.revisions.update(submitted_for_moderation=False)
|
page.revisions.update(submitted_for_moderation=False)
|
||||||
|
|
||||||
|
if page.live:
|
||||||
|
page_published.send(sender=page.specific_class, instance=page.specific)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '"' + unicode(self.page) + '" at ' + unicode(self.created_at)
|
return '"' + unicode(self.page) + '" at ' + unicode(self.created_at)
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue