diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-10-17 17:31:09 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-10-17 17:31:09 +0200 | 
| commit | 7811ea2ab5bc31c66228d02e84ac2208be56b5e8 (patch) | |
| tree | faab2c98880088d074b0fd8a979f86af967e0736 | |
| parent | f9750f82ce0cf347491b2a8584811339fd8e52c6 (diff) | |
| download | Ishtar-7811ea2ab5bc31c66228d02e84ac2208be56b5e8.tar.bz2 Ishtar-7811ea2ab5bc31c66228d02e84ac2208be56b5e8.zip | |
JSON: add JSON fields to manage dynamic data schema - add table to administrate display of theses fields (refs #3077)
7 files changed, 319 insertions, 2 deletions
| diff --git a/archaeological_context_records/migrations/0012_auto_20171017_1730.py b/archaeological_context_records/migrations/0012_auto_20171017_1730.py new file mode 100644 index 000000000..49a3ee5f3 --- /dev/null +++ b/archaeological_context_records/migrations/0012_auto_20171017_1730.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-10-17 17:30 +from __future__ import unicode_literals + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_context_records', '0011_auto_20171012_1316'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='contextrecord', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicalcontextrecord', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +    ] diff --git a/archaeological_files/migrations/0010_auto_20171017_1730.py b/archaeological_files/migrations/0010_auto_20171017_1730.py new file mode 100644 index 000000000..d2e6dde4c --- /dev/null +++ b/archaeological_files/migrations/0010_auto_20171017_1730.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-10-17 17:30 +from __future__ import unicode_literals + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_files', '0009_auto_20171012_1316'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='file', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicalfile', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +    ] diff --git a/archaeological_finds/migrations/0012_auto_20171017_1730.py b/archaeological_finds/migrations/0012_auto_20171017_1730.py new file mode 100644 index 000000000..7ddca1e18 --- /dev/null +++ b/archaeological_finds/migrations/0012_auto_20171017_1730.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-10-17 17:30 +from __future__ import unicode_literals + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_finds', '0011_auto_20171012_1316'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='basefind', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='find', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicalbasefind', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicalfind', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicaltreatment', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicaltreatmentfile', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='property', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='treatment', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='treatmentfile', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +    ] diff --git a/archaeological_operations/migrations/0011_auto_20171017_1730.py b/archaeological_operations/migrations/0011_auto_20171017_1730.py new file mode 100644 index 000000000..8621cfcfe --- /dev/null +++ b/archaeological_operations/migrations/0011_auto_20171017_1730.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-10-17 17:30 +from __future__ import unicode_literals + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_operations', '0010_auto_20171012_1316'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='administrativeact', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='archaeologicalsite', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicaladministrativeact', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicaloperation', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='operation', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='parcel', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='parcelowner', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +    ] diff --git a/archaeological_warehouse/migrations/0010_auto_20171017_1730.py b/archaeological_warehouse/migrations/0010_auto_20171017_1730.py new file mode 100644 index 000000000..ca5873ddc --- /dev/null +++ b/archaeological_warehouse/migrations/0010_auto_20171017_1730.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-10-17 17:30 +from __future__ import unicode_literals + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('archaeological_warehouse', '0009_auto_20171012_1316'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='collection', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='container', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='warehouse', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +    ] diff --git a/ishtar_common/migrations/0018_auto_20171017_1730.py b/ishtar_common/migrations/0018_auto_20171017_1730.py new file mode 100644 index 000000000..5c974be17 --- /dev/null +++ b/ishtar_common/migrations/0018_auto_20171017_1730.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-10-17 17:30 +from __future__ import unicode_literals + +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('contenttypes', '0002_remove_content_type_name'), +        ('ishtar_common', '0017_auto_20171016_1320'), +    ] + +    operations = [ +        migrations.CreateModel( +            name='JsonDataField', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('name', models.CharField(max_length=200, verbose_name='Name')), +                ('key', models.CharField(help_text='Value of the key in the JSON schema. For hierarchical key use "__" to explain it. For instance the key \'my_subkey\' with data such as {\'my_key\': {\'my_subkey\': \'value\'}} will be reached with my_key__my_subkey.', max_length=200, verbose_name='Key')), +                ('display', models.BooleanField(default=True, verbose_name='Display')), +                ('order', models.IntegerField(default=10, verbose_name='Order')), +                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), +            ], +            options={ +                'verbose_name': 'Json data - Field', +                'verbose_name_plural': 'Json data - Fields', +            }, +        ), +        migrations.CreateModel( +            name='JsonDataSection', +            fields=[ +                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), +                ('name', models.CharField(max_length=200, verbose_name='Name')), +                ('order', models.IntegerField(default=10, verbose_name='Order')), +                ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), +            ], +            options={ +                'ordering': ['name'], +                'verbose_name': 'Json data - Menu', +                'verbose_name_plural': 'Json data - Menus', +            }, +        ), +        migrations.AddField( +            model_name='historicalorganization', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='historicalperson', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='organization', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='person', +            name='data', +            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), +        ), +        migrations.AddField( +            model_name='jsondatafield', +            name='section', +            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.JsonDataSection'), +        ), +    ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 2904e51cd..8d4511809 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -35,6 +35,7 @@ import tempfile  import time  from django.conf import settings +from django.contrib.postgres.fields import JSONField  from django.contrib.postgres.search import SearchVectorField, SearchVector  from django.core.cache import cache  from django.core.exceptions import ObjectDoesNotExist, ValidationError @@ -909,6 +910,55 @@ class BulkUpdatedItem(object):          return transaction_id, False +class JsonDataSection(models.Model): +    content_type = models.ForeignKey(ContentType) +    name = models.CharField(_(u"Name"), max_length=200) +    order = models.IntegerField(_(u"Order"), default=10) + +    class Meta: +        verbose_name = _(u"Json data - Menu") +        verbose_name_plural = _(u"Json data - Menus") +        ordering = ['name'] + +    def __unicode__(self): +        return u"{} - {}".format(self.content_type, self.name) + + +class JsonDataField(models.Model): +    name = models.CharField(_(u"Name"), max_length=200) +    content_type = models.ForeignKey(ContentType) +    key = models.CharField( +        _(u"Key"), max_length=200, +        help_text=_(u"Value of the key in the JSON schema. For hierarchical " +                    u"key use \"__\" to explain it. For instance the key " +                    u"'my_subkey' with data such as {'my_key': {'my_subkey': " +                    u"'value'}} will be reached with my_key__my_subkey.")) +    display = models.BooleanField(_(u"Display"), default=True) +    order = models.IntegerField(_(u"Order"), default=10) +    section = models.ForeignKey(JsonDataSection, blank=True, null=True) + +    class Meta: +        verbose_name = _(u"Json data - Field") +        verbose_name_plural = _(u"Json data - Fields") + +    def __unicode__(self): +        return u"{} - {}".format(self.content_type, self.name) + +    def clean(self): +        if not self.section: +            return +        if self.section.content_type != self.content_type: +            raise ValidationError( +                _(u"Content type of the field and of the menu do not match")) + + +class JsonData(models.Model): +    data = JSONField(null=True, blank=True) + +    class Meta: +        abstract = True + +  class Imported(models.Model):      imports = models.ManyToManyField(          Import, blank=True, @@ -993,10 +1043,10 @@ class FullSearch(models.Model):          return changed -class BaseHistorizedItem(FullSearch, Imported): +class BaseHistorizedItem(FullSearch, Imported, JsonData):      """      Historized item with external ID management. -    All historized items are searcheable +    All historized items are searcheable and have a data json field      """      IS_BASKET = False      EXTERNAL_ID_KEY = '' | 
