From 024987adfa31f70e2c1536f11acbc18097409756 Mon Sep 17 00:00:00 2001
From: Eva Bardou <ebardou@teklia.com>
Date: Tue, 18 May 2021 15:44:22 +0200
Subject: [PATCH] Replace the FK towards Document on OcrModel by a M2M relation

---
 app/apps/core/admin.py                        |  6 ++
 .../migrations/0045_auto_20210518_1235.py     | 55 +++++++++++++++++++
 app/apps/core/models.py                       | 17 +++++-
 3 files changed, 75 insertions(+), 3 deletions(-)
 create mode 100644 app/apps/core/migrations/0045_auto_20210518_1235.py

diff --git a/app/apps/core/admin.py b/app/apps/core/admin.py
index bf33b7d0..8a0957fb 100644
--- a/app/apps/core/admin.py
+++ b/app/apps/core/admin.py
@@ -6,6 +6,7 @@ from core.models import (Document,
                          DocumentMetadata,
                          LineTranscription,
                          OcrModel,
+                         OcrModelDocument,
                          Script,
                          DocumentType,
                          DocumentPartType,
@@ -44,6 +45,10 @@ class OcrModelAdmin(admin.ModelAdmin):
     list_display = ['name', 'job', 'owner', 'script', 'training']
 
 
+class OcrModelDocumentAdmin(admin.ModelAdmin):
+    list_display = ['document', 'ocr_model', 'trained_on', 'executed_on', 'created']
+
+
 admin.site.register(Document, DocumentAdmin)
 admin.site.register(DocumentPart, DocumentPartAdmin)
 admin.site.register(LineTranscription, LineTranscriptionAdmin)
@@ -54,3 +59,4 @@ admin.site.register(LineType)
 admin.site.register(Script, ScriptAdmin)
 admin.site.register(Metadata)
 admin.site.register(OcrModel, OcrModelAdmin)
+admin.site.register(OcrModelDocument, OcrModelDocumentAdmin)
diff --git a/app/apps/core/migrations/0045_auto_20210518_1235.py b/app/apps/core/migrations/0045_auto_20210518_1235.py
new file mode 100644
index 00000000..a31d6819
--- /dev/null
+++ b/app/apps/core/migrations/0045_auto_20210518_1235.py
@@ -0,0 +1,55 @@
+# Generated by Django 2.2.19 on 2021-05-18 12:35
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+def populate_m2m(apps, schema_editor):
+    OcrModel = apps.get_model('core', 'OcrModel')
+    OcrModelDocument = apps.get_model('core', 'OcrModelDocument')
+
+    OcrModelDocument.objects.bulk_create([
+        OcrModelDocument(
+            document_id = model.document_id,
+            ocr_model_id = model.id,
+            trained_on = False,
+            executed_on = True,
+        ) for model in OcrModel.objects.exclude(document__isnull=True)
+    ])
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0044_auto_20210520_1332'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='OcrModelDocument',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('created', models.DateTimeField(auto_now_add=True)),
+                ('trained_on', models.BooleanField()),
+                ('executed_on', models.BooleanField()),
+                ('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ocr_model_documents', to='core.Document')),
+                ('ocr_model', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ocr_model_documents', to='core.OcrModel')),
+            ],
+            options={
+                'unique_together': {('document', 'ocr_model')},
+            },
+        ),
+        migrations.AddField(
+            model_name='ocrmodel',
+            name='documents',
+            field=models.ManyToManyField(related_name='ocr_models', through='core.OcrModelDocument', to='core.Document'),
+        ),
+        migrations.RunPython(
+            populate_m2m,
+            reverse_code=migrations.RunPython.noop,
+        ),
+        migrations.RemoveField(
+            model_name='ocrmodel',
+            name='document',
+        ),
+    ]
diff --git a/app/apps/core/models.py b/app/apps/core/models.py
index 9299c1bc..c0dd0046 100644
--- a/app/apps/core/models.py
+++ b/app/apps/core/models.py
@@ -1105,9 +1105,9 @@ class OcrModel(Versioned, models.Model):
     training_accuracy = models.FloatField(default=0.0)
     training_total = models.IntegerField(default=0)
     training_errors = models.IntegerField(default=0)
-    document = models.ForeignKey(Document,
-                                 related_name='ocr_models',
-                                 default=None, on_delete=models.CASCADE)
+    documents = models.ManyToManyField(Document,
+                                       through='core.OcrModelDocument',
+                                       related_name='ocr_models')
     script = models.ForeignKey(Script, blank=True, null=True, on_delete=models.SET_NULL)
 
     version_ignore_fields = ('name', 'owner', 'document', 'script', 'training')
@@ -1178,6 +1178,17 @@ class OcrModel(Versioned, models.Model):
         super().delete_revision(revision)
 
 
+class OcrModelDocument(models.Model):
+    document = models.ForeignKey(Document, on_delete=models.CASCADE, related_name='ocr_model_documents')
+    ocr_model = models.ForeignKey(OcrModel, on_delete=models.CASCADE, related_name='ocr_model_documents')
+    created = models.DateTimeField(auto_now_add=True)
+    trained_on = models.BooleanField()
+    executed_on = models.BooleanField()
+
+    class Meta:
+        unique_together = (('document', 'ocr_model'),)
+
+
 @receiver(pre_delete, sender=DocumentPart, dispatch_uid='thumbnails_delete_signal')
 def delete_thumbnails(sender, instance, using, **kwargs):
     thumbnailer = get_thumbnailer(instance.image)
-- 
GitLab