Add fields for scheduled publishing

Also add a clean method to Page to check that expiry date is in the
future and that go live date is before expiry date. In order to display
the correct error message the views/pages.py view has to be changed to
display the error message from clean.

Finally add the migration for the new fields.
This commit is contained in:
Serafeim Papastefanos 2014-04-15 21:55:24 +03:00
parent d3ac6c0728
commit e4c38302e0
3 changed files with 156 additions and 5 deletions

View file

@ -7,7 +7,7 @@ from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.decorators import permission_required
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext as _
from django.views.decorators.vary import vary_on_headers
from wagtail.wagtailadmin.edit_handlers import TabbedInterface, ObjectList
@ -199,7 +199,10 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_
return redirect('wagtailadmin_explore', page.get_parent().id)
else:
messages.error(request, _("The page could not be created due to errors."))
if form.errors and form.errors.get('__all__'):
messages.error(request, _("The page could not be created: ") + ', '.join(form.errors['__all__']))
else:
messages.error(request, _("The page could not be created due to errors."))
edit_handler = edit_handler_class(instance=page, form=form)
else:
form = form_class(instance=page)

View file

@ -0,0 +1,130 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'PageRevision.approved_go_live_datetime'
db.add_column(u'wagtailcore_pagerevision', 'approved_go_live_datetime',
self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True),
keep_default=False)
# Adding field 'Page.go_live_datetime'
db.add_column(u'wagtailcore_page', 'go_live_datetime',
self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True),
keep_default=False)
# Adding field 'Page.expiry_datetime'
db.add_column(u'wagtailcore_page', 'expiry_datetime',
self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True),
keep_default=False)
# Adding field 'Page.expired'
db.add_column(u'wagtailcore_page', 'expired',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
def backwards(self, orm):
# Deleting field 'PageRevision.approved_go_live_datetime'
db.delete_column(u'wagtailcore_pagerevision', 'approved_go_live_datetime')
# Deleting field 'Page.go_live_datetime'
db.delete_column(u'wagtailcore_page', 'go_live_datetime')
# Deleting field 'Page.expiry_datetime'
db.delete_column(u'wagtailcore_page', 'expiry_datetime')
# Deleting field 'Page.expired'
db.delete_column(u'wagtailcore_page', 'expired')
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'wagtailcore.grouppagepermission': {
'Meta': {'object_name': 'GroupPagePermission'},
'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'page_permissions'", 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_permissions'", 'to': u"orm['wagtailcore.Page']"}),
'permission_type': ('django.db.models.fields.CharField', [], {'max_length': '20'})
},
u'wagtailcore.page': {
'Meta': {'object_name': 'Page'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pages'", 'to': u"orm['contenttypes.ContentType']"}),
'depth': ('django.db.models.fields.PositiveIntegerField', [], {}),
'expired': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'expiry_datetime': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'go_live_datetime': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'has_unpublished_changes': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'live': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'numchild': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'owned_pages'", 'null': 'True', 'to': u"orm['auth.User']"}),
'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'search_description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'seo_title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'show_in_menus': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'url_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'})
},
u'wagtailcore.pagerevision': {
'Meta': {'object_name': 'PageRevision'},
'approved_go_live_datetime': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'content_json': ('django.db.models.fields.TextField', [], {}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': u"orm['wagtailcore.Page']"}),
'submitted_for_moderation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'})
},
u'wagtailcore.site': {
'Meta': {'object_name': 'Site'},
'hostname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_default_site': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'port': ('django.db.models.fields.IntegerField', [], {'default': '80'}),
'root_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sites_rooted_here'", 'to': u"orm['wagtailcore.Page']"})
}
}
complete_apps = ['wagtailcore']

View file

@ -7,10 +7,13 @@ from django.db import models, connection, transaction
from django.db.models import get_model, Q
from django.http import Http404
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import Group
from django.conf import settings
from django.template.response import TemplateResponse
from django.utils import timezone
from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from wagtail.wagtailcore.util import camelcase_to_underscore
@ -234,6 +237,10 @@ class Page(MP_Node, ClusterableModel, Indexed):
show_in_menus = models.BooleanField(default=False, help_text=_("Whether a link to this page will appear in automatically generated menus"))
search_description = models.TextField(blank=True)
go_live_datetime = models.DateTimeField(verbose_name=_("Go live date/time"), blank=True, null=True)
expiry_datetime = models.DateTimeField(verbose_name=_("Expiry date/time"), blank=True, null=True)
expired = models.BooleanField(default=False, editable=False)
indexed_fields = {
'title': {
'type': 'string',
@ -320,7 +327,7 @@ class Page(MP_Node, ClusterableModel, Indexed):
SET url_path = %s || substring(url_path from %s)
WHERE path LIKE %s AND id <> %s
"""
cursor.execute(update_statement,
cursor.execute(update_statement,
[new_url_path, len(old_url_path) + 1, self.path + '%', self.id])
@property
@ -399,8 +406,8 @@ class Page(MP_Node, ClusterableModel, Indexed):
def serve(self, request):
return TemplateResponse(
request,
self.get_template(request),
request,
self.get_template(request),
self.get_context(request)
)
@ -448,6 +455,16 @@ class Page(MP_Node, ClusterableModel, Indexed):
if self.url_path.startswith(root_path):
return ('' if current_site.id == id else root_url) + self.url_path[len(root_path) - 1:]
def clean(self):
super(Page, self).clean()
if self.go_live_datetime and self.expiry_datetime:
if self.go_live_datetime > self.expiry_datetime:
raise ValidationError(ugettext('Go live date/time should be before expiry datetime.'))
if self.expiry_datetime and self.expiry_datetime < timezone.now():
raise ValidationError(ugettext('Expiry date/time should be in the future'))
@classmethod
def search(cls, query_string, show_unpublished=False, search_title_only=False, extra_filters={}, prefetch_related=[], path=None):
# Filters
@ -642,6 +659,7 @@ class PageRevision(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
content_json = models.TextField()
approved_go_live_datetime = models.DateTimeField(null=True, blank=True)
objects = models.Manager()
submitted_revisions = SubmittedRevisionsManager()