diff --git a/CHANGELOG.rst b/CHANGELOG.rst index afc8d757..db162389 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,13 @@ are used for versioning (schema follows below): 0.3.4 to 0.4). - All backwards incompatible changes are mentioned in this document. +0.9.12 +------ +2016-11-02 + +- Better debugging. +- Upgrade example FeinCMS integration to work with 1.12. + 0.9.11 ------ 2016-11-01 diff --git a/docs/index.rst b/docs/index.rst index 84d40669..54712daa 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1985,8 +1985,8 @@ element- and form handler- plugins. shown in case of missing form element handlers, set this to False in your settings module. Default value is True. -Tests -===== +Testing +======= Project is covered by test (functional- and browser-tests). To test type: @@ -2000,7 +2000,7 @@ install the test requirements: .. code:: sh - pip install -r examples/simple/requirements/common_test_requirements.txt + pip install -r examples/requirements/common_test_requirements.txt Selenium -------- diff --git a/examples/requirements/feincms.txt b/examples/requirements/feincms_1_10.txt similarity index 100% rename from examples/requirements/feincms.txt rename to examples/requirements/feincms_1_10.txt diff --git a/examples/requirements/feincms_1_12.txt b/examples/requirements/feincms_1_12.txt new file mode 100644 index 00000000..dc5b3403 --- /dev/null +++ b/examples/requirements/feincms_1_12.txt @@ -0,0 +1,5 @@ +-r django_1_9.txt + +FeinCMS==1.12.1 +django-mptt==0.8.6 +django-tinymce==2.4.0 diff --git a/examples/simple/page/migrations/0001_initial.py b/examples/simple/page/migrations/0001_initial.py index 7638ed71..04a0ac8d 100644 --- a/examples/simple/page/migrations/0001_initial.py +++ b/examples/simple/page/migrations/0001_initial.py @@ -1,133 +1,116 @@ # -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models +# Generated by Django 1.9.10 on 2016-10-17 20:45 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import feincms.contrib.richtext +import feincms.extensions.base +import feincms.module.mixins +import fobi.integration.processors -class Migration(SchemaMigration): +class Migration(migrations.Migration): - def forwards(self, orm): - # Adding model 'Page' - db.create_table(u'page_page', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - (u'lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), - (u'rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), - (u'tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), - (u'level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), - ('active', self.gf('django.db.models.fields.BooleanField')(default=True)), - ('title', self.gf('django.db.models.fields.CharField')(max_length=200)), - ('slug', self.gf('django.db.models.fields.SlugField')(max_length=150)), - ('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name=u'children', null=True, to=orm['page.Page'])), - ('in_navigation', self.gf('django.db.models.fields.BooleanField')(default=False)), - ('override_url', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), - ('redirect_to', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), - ('_cached_url', self.gf('django.db.models.fields.CharField')(default=u'', max_length=255, db_index=True, blank=True)), - (u'template_key', self.gf('django.db.models.fields.CharField')(default='page_base', max_length=255)), - )) - db.send_create_signal(u'page', ['Page']) + initial = True - # Adding model 'FobiFormWidget' - db.create_table(u'page_page_fobiformwidget', ( - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('form_entry', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['fobi.FormEntry'])), - (u'parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name=u'fobiformwidget_set', to=orm['page.Page'])), - (u'region', self.gf('django.db.models.fields.CharField')(max_length=255)), - (u'ordering', self.gf('django.db.models.fields.IntegerField')(default=0)), - )) - db.send_create_signal(u'page', ['FobiFormWidget']) + dependencies = [ + ('fobi', '0010_formwizardhandler'), + ] - - def backwards(self, orm): - # Deleting model 'Page' - db.delete_table(u'page_page') - - # Deleting model 'FobiFormWidget' - db.delete_table(u'page_page_fobiformwidget') - - - 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'fobi.formentry': { - 'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormEntry'}, - 'form_wizard_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormWizardEntry']", 'null': 'True', 'blank': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'position': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) - }, - u'fobi.formwizardentry': { - 'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormWizardEntry'}, - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) - }, - u'page.fobiformwidget': { - 'Meta': {'ordering': "[u'ordering']", 'object_name': 'FobiFormWidget', 'db_table': "u'page_page_fobiformwidget'"}, - 'form_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormEntry']"}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - u'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - u'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'fobiformwidget_set'", 'to': u"orm['page.Page']"}), - u'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - u'page.page': { - 'Meta': {'ordering': "[u'tree_id', u'lft']", 'object_name': 'Page'}, - '_cached_url': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'db_index': 'True', 'blank': 'True'}), - 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'override_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'children'", 'null': 'True', 'to': u"orm['page.Page']"}), - 'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), - u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150'}), - u'template_key': ('django.db.models.fields.CharField', [], {'default': "'page_base'", 'max_length': '255'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) - } - } - - complete_apps = ['page'] \ No newline at end of file + operations = [ + migrations.CreateModel( + name='FobiFormWidget', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('form_template_name', models.CharField(blank=True, choices=[(b'fobi/bootstrap3_extras/view_embed_form_entry_ajax.html', b'Custom bootstrap3 embed form view template')], help_text='Template to render the form with.', max_length=255, null=True, verbose_name='Form template name')), + ('hide_form_title', models.BooleanField(default=False, help_text='If checked, no form title is shown.', verbose_name='Hide form title')), + ('form_title', models.CharField(blank=True, help_text='Overrides the default form title.', max_length=255, null=True, verbose_name='Form title')), + ('form_submit_button_text', models.CharField(blank=True, help_text='Overrides the default form submit button text.', max_length=255, null=True, verbose_name='Submit button text')), + ('success_page_template_name', models.CharField(blank=True, choices=[(b'fobi/bootstrap3_extras/embed_form_entry_submitted_ajax.html', b'Custom bootstrap3 embed form entry submitted template')], help_text='Template to render the success page with.', max_length=255, null=True, verbose_name='Success page template name')), + ('hide_success_page_title', models.BooleanField(default=False, help_text='If checked, no success page title is shown.', verbose_name='Hide success page title')), + ('success_page_title', models.CharField(blank=True, help_text='Overrides the default success page title.', max_length=255, null=True, verbose_name='Succes page title')), + ('success_page_text', models.TextField(blank=True, help_text='Overrides the default success page text.', null=True, verbose_name='Succes page text')), + ('region', models.CharField(max_length=255)), + ('ordering', models.IntegerField(default=0, verbose_name='ordering')), + ('form_entry', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='fobi.FormEntry', verbose_name='Form')), + ], + options={ + 'ordering': ['ordering'], + 'abstract': False, + 'verbose_name_plural': 'fobi form widgets', + 'db_table': 'page_page_fobiformwidget', + 'verbose_name': 'fobi form widget', + 'permissions': [], + }, + bases=(models.Model, fobi.integration.processors.IntegrationProcessor), + ), + migrations.CreateModel( + name='Page', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('active', models.BooleanField(default=True, verbose_name='active')), + ('title', models.CharField(help_text='This title is also used for navigation menu items.', max_length=200, verbose_name='title')), + ('slug', models.SlugField(help_text='This is used to build the URL for this page', max_length=150, verbose_name='slug')), + ('in_navigation', models.BooleanField(default=False, verbose_name='in navigation')), + ('override_url', models.CharField(blank=True, help_text="Override the target URL. Be sure to include slashes at the beginning and at the end if it is a local URL. This affects both the navigation and subpages' URLs.", max_length=255, verbose_name='override URL')), + ('redirect_to', models.CharField(blank=True, help_text='Target URL for automatic redirects or the primary key of a page.', max_length=255, verbose_name='redirect to')), + ('_cached_url', models.CharField(blank=True, db_index=True, default='', editable=False, max_length=255, verbose_name='Cached URL')), + ('lft', models.PositiveIntegerField(db_index=True, editable=False)), + ('rght', models.PositiveIntegerField(db_index=True, editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(db_index=True, editable=False)), + ('language', models.CharField(choices=[(b'en', b'English'), (b'hy', b'Armenian'), (b'nl', b'Dutch'), (b'ru', b'Russian'), (b'de', b'German')], default=b'en', max_length=10, verbose_name='language')), + ('template_key', models.CharField(choices=[(b'page_base', 'Base template')], default=b'page_base', max_length=255, verbose_name='template')), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='page.Page', verbose_name='Parent')), + ('translation_of', models.ForeignKey(blank=True, help_text='Leave this empty for entries in the primary language.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='page.Page', verbose_name='translation of')), + ], + options={ + 'ordering': ['tree_id', 'lft'], + 'verbose_name': 'page', + 'verbose_name_plural': 'pages', + }, + bases=(models.Model, feincms.extensions.base.ExtensionsMixin, feincms.module.mixins.ContentModelMixin), + ), + migrations.CreateModel( + name='RawContent', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField(blank=True, verbose_name='content')), + ('region', models.CharField(max_length=255)), + ('ordering', models.IntegerField(default=0, verbose_name='ordering')), + ('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rawcontent_set', to='page.Page')), + ], + options={ + 'ordering': ['ordering'], + 'abstract': False, + 'verbose_name_plural': 'raw contents', + 'db_table': 'page_page_rawcontent', + 'verbose_name': 'raw content', + 'permissions': [], + }, + ), + migrations.CreateModel( + name='RichTextContent', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('region', models.CharField(max_length=255)), + ('ordering', models.IntegerField(default=0, verbose_name='ordering')), + ('text', feincms.contrib.richtext.RichTextField(blank=True, verbose_name='text')), + ('parent', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='richtextcontent_set', to='page.Page')), + ], + options={ + 'ordering': ['ordering'], + 'abstract': False, + 'verbose_name_plural': 'rich texts', + 'db_table': 'page_page_richtextcontent', + 'verbose_name': 'rich text', + 'permissions': [], + }, + ), + migrations.AddField( + model_name='fobiformwidget', + name='parent', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fobiformwidget_set', to='page.Page'), + ), + ] diff --git a/examples/simple/page/south_migrations/0001_initial.py b/examples/simple/page/south_migrations/0001_initial.py new file mode 100644 index 00000000..7638ed71 --- /dev/null +++ b/examples/simple/page/south_migrations/0001_initial.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'Page' + db.create_table(u'page_page', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + (u'lft', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), + (u'rght', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), + (u'tree_id', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), + (u'level', self.gf('django.db.models.fields.PositiveIntegerField')(db_index=True)), + ('active', self.gf('django.db.models.fields.BooleanField')(default=True)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=200)), + ('slug', self.gf('django.db.models.fields.SlugField')(max_length=150)), + ('parent', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name=u'children', null=True, to=orm['page.Page'])), + ('in_navigation', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('override_url', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), + ('redirect_to', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), + ('_cached_url', self.gf('django.db.models.fields.CharField')(default=u'', max_length=255, db_index=True, blank=True)), + (u'template_key', self.gf('django.db.models.fields.CharField')(default='page_base', max_length=255)), + )) + db.send_create_signal(u'page', ['Page']) + + # Adding model 'FobiFormWidget' + db.create_table(u'page_page_fobiformwidget', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('form_entry', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['fobi.FormEntry'])), + (u'parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name=u'fobiformwidget_set', to=orm['page.Page'])), + (u'region', self.gf('django.db.models.fields.CharField')(max_length=255)), + (u'ordering', self.gf('django.db.models.fields.IntegerField')(default=0)), + )) + db.send_create_signal(u'page', ['FobiFormWidget']) + + + def backwards(self, orm): + # Deleting model 'Page' + db.delete_table(u'page_page') + + # Deleting model 'FobiFormWidget' + db.delete_table(u'page_page_fobiformwidget') + + + 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'fobi.formentry': { + 'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormEntry'}, + 'form_wizard_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormWizardEntry']", 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'position': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'fobi.formwizardentry': { + 'Meta': {'unique_together': "(('user', 'slug'), ('user', 'name'))", 'object_name': 'FormWizardEntry'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_cloneable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'slug': ('autoslug.fields.AutoSlugField', [], {'unique': 'True', 'max_length': '50', 'populate_from': "'name'", 'unique_with': '()'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'page.fobiformwidget': { + 'Meta': {'ordering': "[u'ordering']", 'object_name': 'FobiFormWidget', 'db_table': "u'page_page_fobiformwidget'"}, + 'form_entry': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['fobi.FormEntry']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + u'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + u'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'fobiformwidget_set'", 'to': u"orm['page.Page']"}), + u'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + u'page.page': { + 'Meta': {'ordering': "[u'tree_id', u'lft']", 'object_name': 'Page'}, + '_cached_url': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '255', 'db_index': 'True', 'blank': 'True'}), + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + u'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + u'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'override_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'children'", 'null': 'True', 'to': u"orm['page.Page']"}), + 'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + u'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150'}), + u'template_key': ('django.db.models.fields.CharField', [], {'default': "'page_base'", 'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + u'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) + } + } + + complete_apps = ['page'] \ No newline at end of file diff --git a/examples/simple/page/migrations/0002_auto__add_field_page_language__add_field_page_translation_of.py b/examples/simple/page/south_migrations/0002_auto__add_field_page_language__add_field_page_translation_of.py similarity index 100% rename from examples/simple/page/migrations/0002_auto__add_field_page_language__add_field_page_translation_of.py rename to examples/simple/page/south_migrations/0002_auto__add_field_page_language__add_field_page_translation_of.py diff --git a/examples/simple/page/migrations/0003_auto__add_richtextcontent__add_rawcontent.py b/examples/simple/page/south_migrations/0003_auto__add_richtextcontent__add_rawcontent.py similarity index 100% rename from examples/simple/page/migrations/0003_auto__add_richtextcontent__add_rawcontent.py rename to examples/simple/page/south_migrations/0003_auto__add_richtextcontent__add_rawcontent.py diff --git a/examples/simple/page/migrations/0004_auto__add_field_fobiformwidget_form_template_name__add_field_fobiformw.py b/examples/simple/page/south_migrations/0004_auto__add_field_fobiformwidget_form_template_name__add_field_fobiformw.py similarity index 100% rename from examples/simple/page/migrations/0004_auto__add_field_fobiformwidget_form_template_name__add_field_fobiformw.py rename to examples/simple/page/south_migrations/0004_auto__add_field_fobiformwidget_form_template_name__add_field_fobiformw.py diff --git a/examples/simple/page/south_migrations/__init__.py b/examples/simple/page/south_migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/simple/runserver/bootstrap3-theme-django-1-9-feincms_integration.sh b/examples/simple/runserver/bootstrap3-theme-django-1-9-feincms_integration.sh new file mode 100755 index 00000000..da4363f1 --- /dev/null +++ b/examples/simple/runserver/bootstrap3-theme-django-1-9-feincms_integration.sh @@ -0,0 +1 @@ +./manage.py runserver 0.0.0.0:8000 --traceback -v 3 --settings=settings.bootstrap3_theme_django_1_7_feincms --traceback -v 3 diff --git a/examples/simple/settings/bootstrap3_theme_django_1_9_feincms.py b/examples/simple/settings/bootstrap3_theme_django_1_9_feincms.py new file mode 100644 index 00000000..032a0ba0 --- /dev/null +++ b/examples/simple/settings/bootstrap3_theme_django_1_9_feincms.py @@ -0,0 +1,30 @@ +from .base import * + +INSTALLED_APPS = list(INSTALLED_APPS) + +try: + INSTALLED_APPS.remove('south') if 'south' in INSTALLED_APPS else None + # INSTALLED_APPS.remove('tinymce') if 'tinymce' in INSTALLED_APPS else None + INSTALLED_APPS.remove('admin_tools.dashboard') \ + if 'admin_tools.dashboard' in INSTALLED_APPS \ + else None + + INSTALLED_APPS += [ + 'feincms', # FeinCMS + + 'fobi.contrib.apps.feincms_integration', # Fobi FeinCMS app + + 'page', # Example + ] +except Exception as e: + pass + + +FEINCMS_RICHTEXT_INIT_CONTEXT = { + 'TINYMCE_JS_URL': STATIC_URL + 'tiny_mce/tiny_mce.js', +} + +MIGRATION_MODULES = { + 'fobi': 'fobi.migrations', + 'db_store': 'fobi.contrib.plugins.form_handlers.db_store.migrations', +} diff --git a/scripts/install_django_1_7_feincms.sh b/scripts/install_django_1_7_feincms.sh index 758bba07..8dac1868 100755 --- a/scripts/install_django_1_7_feincms.sh +++ b/scripts/install_django_1_7_feincms.sh @@ -1,5 +1,4 @@ -#pip install -r examples/requirements/django_1_7.txt -pip install -r examples/requirements/feincms.txt +pip install -r examples/requirements/feincms_1_10.txt python setup.py install mkdir -p examples/logs examples/db examples/media examples/media/static examples/media/fobi_plugins/content_image mkdir -p examples/media/fobi_plugins/file diff --git a/scripts/install_django_1_9_feincms.sh b/scripts/install_django_1_9_feincms.sh new file mode 100755 index 00000000..c7322d41 --- /dev/null +++ b/scripts/install_django_1_9_feincms.sh @@ -0,0 +1,8 @@ +pip install -r examples/requirements/feincms_1_12.txt +python setup.py install +mkdir -p examples/logs examples/db examples/media examples/media/static examples/media/fobi_plugins/content_image +mkdir -p examples/media/fobi_plugins/file +python examples/simple/manage.py collectstatic --noinput --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3 +python examples/simple/manage.py syncdb --noinput --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3 +python examples/simple/manage.py migrate --noinput --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3 +python examples/simple/manage.py fobi_create_test_data --settings=settings.bootstrap3_theme_django_1_9_feincms --traceback -v 3 diff --git a/scripts/reinstall_django_1_9_feincms.sh b/scripts/reinstall_django_1_9_feincms.sh new file mode 100755 index 00000000..e1a1e115 --- /dev/null +++ b/scripts/reinstall_django_1_9_feincms.sh @@ -0,0 +1,3 @@ +reset +./scripts/uninstall.sh +./scripts/install_django_1_9_feincms.sh \ No newline at end of file diff --git a/setup.py b/setup.py index 99575981..2611d186 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ import sys from distutils.version import LooseVersion from setuptools import setup, find_packages -version = '0.9.11' +version = '0.9.12' # *************************************************************************** # ************************** Django version ********************************* diff --git a/src/fobi/__init__.py b/src/fobi/__init__.py index 3f42cbaa..82177d4f 100644 --- a/src/fobi/__init__.py +++ b/src/fobi/__init__.py @@ -1,6 +1,6 @@ __title__ = 'django-fobi' -__version__ = '0.9.11' -__build__ = 0x00006c +__version__ = '0.9.12' +__build__ = 0x00006d __author__ = 'Artur Barseghyan ' __copyright__ = '2014-2016 Artur Barseghyan' __license__ = 'GPL 2.0/LGPL 2.1' diff --git a/src/fobi/base.py b/src/fobi/base.py index 9481bf63..7f3edacf 100644 --- a/src/fobi/base.py +++ b/src/fobi/base.py @@ -1055,15 +1055,13 @@ class BasePlugin(object): plugin_form = self.get_form() if plugin_form: try: - plugin_form = self.get_form() - if plugin_form: - kwargs = { - 'data': data, - 'files': files, - } - if initial_data: - kwargs.update({'initial': initial_data}) - return plugin_form(**kwargs) + kwargs = { + 'data': data, + 'files': files, + } + if initial_data: + kwargs.update({'initial': initial_data}) + return plugin_form(**kwargs) except Exception as e: if DEBUG: logger.debug(e) @@ -1610,24 +1608,30 @@ class FormHandlerPlugin(BasePlugin): if not form_element_entries: form_element_entries = form_entry.formelemententry_set.all()[:] - try: + if FAIL_ON_ERRORS_IN_FORM_HANDLER_PLUGINS: response = self.run(form_entry, request, form, form_element_entries) if response: return response else: return (True, None) - except Exception as err: - if FAIL_ON_ERRORS_IN_FORM_HANDLER_PLUGINS: - raise err.__class__("Exception: {0}. {1}" - "".format(str(err), - traceback.format_exc())) - logger.error( - "Error in class {0}. Details: " - "{1}. Full trace: {2}".format(self.__class__.__name__, - str(err), traceback.format_exc()) - ) - return (False, err) + else: + try: + response = self.run(form_entry, request, form, + form_element_entries) + if response: + return response + else: + return (True, None) + except Exception as err: + logger.error( + "Error in class {0}. Details: " + "{1}. Full trace: {2}".format( + self.__class__.__name__, + str(err), traceback.format_exc() + ) + ) + return (False, err) def run(self, form_entry, request, form, form_element_entries=None): """Run. diff --git a/src/fobi/models.py b/src/fobi/models.py index 21195027..71516b65 100644 --- a/src/fobi/models.py +++ b/src/fobi/models.py @@ -387,6 +387,7 @@ class FormEntry(models.Model): return reverse('fobi.view_form_entry', kwargs={'slug': self.slug}) +@python_2_unicode_compatible class FormWizardFormEntry(models.Model): """Form wizard form entry. @@ -410,6 +411,9 @@ class FormWizardFormEntry(models.Model): ordering = ['position'] unique_together = (('form_wizard_entry', 'form_entry'),) + def __str__(self): + return "{0} - {1}".format(self.form_wizard_entry, self.form_entry) + @python_2_unicode_compatible class FormFieldsetEntry(models.Model): diff --git a/src/fobi/views.py b/src/fobi/views.py index 67b26724..b6f94820 100644 --- a/src/fobi/views.py +++ b/src/fobi/views.py @@ -669,7 +669,7 @@ def add_form_element_entry(request, form = form_element_plugin.get_initialised_create_form_or_404( data=request.POST, files=request.FILES - ) + ) form.validate_plugin_data(form_elements, request=request) if form.is_valid(): # Saving the plugin form data.