summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commit7811ea2ab5bc31c66228d02e84ac2208be56b5e8 (patch)
treefaab2c98880088d074b0fd8a979f86af967e0736
parentf9750f82ce0cf347491b2a8584811339fd8e52c6 (diff)
downloadIshtar-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)
-rw-r--r--archaeological_context_records/migrations/0012_auto_20171017_1730.py26
-rw-r--r--archaeological_files/migrations/0010_auto_20171017_1730.py26
-rw-r--r--archaeological_finds/migrations/0012_auto_20171017_1730.py61
-rw-r--r--archaeological_operations/migrations/0011_auto_20171017_1730.py51
-rw-r--r--archaeological_warehouse/migrations/0010_auto_20171017_1730.py31
-rw-r--r--ishtar_common/migrations/0018_auto_20171017_1730.py72
-rw-r--r--ishtar_common/models.py54
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 = ''