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 | 99392d78cdf5224fdedcfd8775ab1518307d9f96 (patch) | |
tree | faab2c98880088d074b0fd8a979f86af967e0736 /ishtar_common | |
parent | b72fe64fe6a3239bdb4efa3ee8d3b44ef38fb332 (diff) | |
download | Ishtar-99392d78cdf5224fdedcfd8775ab1518307d9f96.tar.bz2 Ishtar-99392d78cdf5224fdedcfd8775ab1518307d9f96.zip |
JSON: add JSON fields to manage dynamic data schema - add table to administrate display of theses fields (refs #3077)
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/migrations/0018_auto_20171017_1730.py | 72 | ||||
-rw-r--r-- | ishtar_common/models.py | 54 |
2 files changed, 124 insertions, 2 deletions
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 = '' |