From 5a10fa5827e4429ba1c48492fa09a5b560aa51b2 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Sat, 5 Sep 2020 15:41:37 +0200
Subject: [PATCH] Add Branch, AcademicField and Specialty to ontology models

---
 ontology/admin.py                             | 12 +++-
 .../migrations/0006_auto_20200905_1539.py     | 66 +++++++++++++++++++
 ontology/models/__init__.py                   |  6 ++
 ontology/models/academic_field.py             | 45 +++++++++++++
 ontology/models/branch.py                     | 33 ++++++++++
 ontology/models/specialty.py                  | 46 +++++++++++++
 6 files changed, 207 insertions(+), 1 deletion(-)
 create mode 100644 ontology/migrations/0006_auto_20200905_1539.py
 create mode 100644 ontology/models/academic_field.py
 create mode 100644 ontology/models/branch.py
 create mode 100644 ontology/models/specialty.py

diff --git a/ontology/admin.py b/ontology/admin.py
index 644a51dc6..8583454a5 100644
--- a/ontology/admin.py
+++ b/ontology/admin.py
@@ -4,7 +4,17 @@ __license__ = "AGPL v3"
 
 from django.contrib import admin
 
-from .models import Tag, Topic, RelationAsym, RelationSym
+from .models import (
+    Branch, AcademicField, Specialty,
+    Tag, Topic, RelationAsym, RelationSym
+)
+
+
+admin.site.register(Branch)
+
+admin.site.register(AcademicField)
+
+admin.site.register(Specialty)
 
 
 class TagAdmin(admin.ModelAdmin):
diff --git a/ontology/migrations/0006_auto_20200905_1539.py b/ontology/migrations/0006_auto_20200905_1539.py
new file mode 100644
index 000000000..9bdd0a630
--- /dev/null
+++ b/ontology/migrations/0006_auto_20200905_1539.py
@@ -0,0 +1,66 @@
+# Generated by Django 2.2.11 on 2020-09-05 13:39
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('ontology', '0005_auto_20181028_2038'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='AcademicField',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=128)),
+                ('slug', models.SlugField(allow_unicode=True, unique=True)),
+                ('order', models.PositiveSmallIntegerField(unique=True)),
+            ],
+            options={
+                'ordering': ['branch', 'order'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Branch',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=128)),
+                ('slug', models.SlugField(allow_unicode=True, unique=True)),
+                ('order', models.PositiveSmallIntegerField(unique=True)),
+            ],
+            options={
+                'verbose_name_plural': 'branches',
+                'ordering': ['order'],
+            },
+        ),
+        migrations.CreateModel(
+            name='Specialty',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=128)),
+                ('slug', models.SlugField(allow_unicode=True, unique=True)),
+                ('order', models.PositiveSmallIntegerField(unique=True)),
+                ('acad_field', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='specialties', to='ontology.AcademicField')),
+            ],
+            options={
+                'verbose_name_plural': 'specialties',
+                'ordering': ['acad_field', 'order'],
+            },
+        ),
+        migrations.AddField(
+            model_name='academicfield',
+            name='branch',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='academic_fields', to='ontology.Branch'),
+        ),
+        migrations.AddConstraint(
+            model_name='specialty',
+            constraint=models.UniqueConstraint(fields=('acad_field', 'order'), name='unique_acad_field_order'),
+        ),
+        migrations.AddConstraint(
+            model_name='academicfield',
+            constraint=models.UniqueConstraint(fields=('branch', 'order'), name='unique_branch_order'),
+        ),
+    ]
diff --git a/ontology/models/__init__.py b/ontology/models/__init__.py
index 46201bd62..eed5c6d03 100644
--- a/ontology/models/__init__.py
+++ b/ontology/models/__init__.py
@@ -2,6 +2,12 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+from .branch import Branch
+
+from .academic_field import AcademicField
+
+from .specialty import Specialty
+
 from .relations import RelationAsym, RelationSym
 
 from .tag import Tag
diff --git a/ontology/models/academic_field.py b/ontology/models/academic_field.py
new file mode 100644
index 000000000..b372d59e4
--- /dev/null
+++ b/ontology/models/academic_field.py
@@ -0,0 +1,45 @@
+_copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.db import models
+
+
+class AcademicField(models.Model):
+    """
+    A principal division of a branch of knowledge.
+    """
+
+    branch = models.ForeignKey(
+        'ontology.Branch',
+        on_delete=models.CASCADE,
+        related_name='academic_fields'
+    )
+
+    name = models.CharField(
+        max_length=128
+    )
+
+    slug = models.SlugField(
+        unique=True,
+        allow_unicode=True
+    )
+
+    order = models.PositiveSmallIntegerField(
+        unique=True
+    )
+
+    class Meta:
+        constraints = [
+            models.UniqueConstraint(
+                fields=['branch', 'order'],
+                name='unique_branch_order'
+            ),
+        ]
+        ordering = [
+            'branch',
+            'order',
+        ]
+
+    def __str__(self):
+        return self.name
diff --git a/ontology/models/branch.py b/ontology/models/branch.py
new file mode 100644
index 000000000..056ef7438
--- /dev/null
+++ b/ontology/models/branch.py
@@ -0,0 +1,33 @@
+_copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.db import models
+
+
+class Branch(models.Model):
+    """
+    A principal division in the tree of knowledge.
+    """
+
+    name = models.CharField(
+        max_length=128
+    )
+
+    slug = models.SlugField(
+        unique=True,
+        allow_unicode=True
+    )
+
+    order = models.PositiveSmallIntegerField(
+        unique=True
+    )
+
+    class Meta:
+        ordering = [
+            'order',
+        ]
+        verbose_name_plural = 'branches'
+
+    def __str__(self):
+        return self.name
diff --git a/ontology/models/specialty.py b/ontology/models/specialty.py
new file mode 100644
index 000000000..865cc195b
--- /dev/null
+++ b/ontology/models/specialty.py
@@ -0,0 +1,46 @@
+_copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.db import models
+
+
+class Specialty(models.Model):
+    """
+    A principal division of an AcademicField.
+    """
+
+    acad_field = models.ForeignKey(
+        'ontology.AcademicField',
+        on_delete=models.CASCADE,
+        related_name='specialties'
+    )
+
+    name = models.CharField(
+        max_length=128
+    )
+
+    slug = models.SlugField(
+        unique=True,
+        allow_unicode=True
+    )
+
+    order = models.PositiveSmallIntegerField(
+        unique=True
+    )
+
+    class Meta:
+        constraints = [
+            models.UniqueConstraint(
+                fields=['acad_field', 'order'],
+                name='unique_acad_field_order'
+            ),
+        ]
+        ordering = [
+            'acad_field',
+            'order',
+        ]
+        verbose_name_plural = 'specialties'
+
+    def __str__(self):
+        return self.name
-- 
GitLab