diff --git a/wagtail/wagtailcore/migrations/0006_add_uniqueness_constraint_on_group_page_permission.py b/wagtail/wagtailcore/migrations/0006_add_uniqueness_constraint_on_group_page_permission.py new file mode 100644 index 000000000..93b867f0b --- /dev/null +++ b/wagtail/wagtailcore/migrations/0006_add_uniqueness_constraint_on_group_page_permission.py @@ -0,0 +1,110 @@ +# -*- 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 unique constraint on 'GroupPagePermission', fields ['group', 'page', 'permission_type'] + db.create_unique(u'wagtailcore_grouppagepermission', ['group_id', 'page_id', 'permission_type']) + + + def backwards(self, orm): + # Removing unique constraint on 'GroupPagePermission', fields ['group', 'page', 'permission_type'] + db.delete_unique(u'wagtailcore_grouppagepermission', ['group_id', 'page_id', 'permission_type']) + + + 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': {'unique_together': "(('group', 'page', 'permission_type'),)", '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', [], {}), + 'expire_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'expired': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'go_live_at': ('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_at': ('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.pageviewrestriction': { + 'Meta': {'object_name': 'PageViewRestriction'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'view_restrictions'", 'to': u"orm['wagtailcore.Page']"}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'wagtailcore.site': { + 'Meta': {'unique_together': "(('hostname', 'port'),)", 'object_name': 'Site'}, + 'hostname': ('django.db.models.fields.CharField', [], {'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'] \ No newline at end of file diff --git a/wagtail/wagtailcore/models.py b/wagtail/wagtailcore/models.py index 11b6fe7ec..fc2f88f75 100644 --- a/wagtail/wagtailcore/models.py +++ b/wagtail/wagtailcore/models.py @@ -955,6 +955,9 @@ class GroupPagePermission(models.Model): page = models.ForeignKey('Page', related_name='group_permissions') permission_type = models.CharField(max_length=20, choices=PAGE_PERMISSION_TYPE_CHOICES) + class Meta: + unique_together = ('group', 'page', 'permission_type') + class UserPagePermissionsProxy(object): """Helper object that encapsulates all the page permission rules that this user has diff --git a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html index bee5196a6..d43b1cdef 100644 --- a/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html +++ b/wagtail/wagtailusers/templates/wagtailusers/groups/includes/page_permissions_form.html @@ -27,5 +27,12 @@ {{ form.id }} {{ form.ORDER }} {{ form.DELETE }} + {% if form.non_field_errors %} +

+ {% for error in form.non_field_errors %} + {{ error|escape }} + {% endfor %} +

+ {% endif %}