From 46187659ed7a91c11030308cdfb2879413c14526 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= <aurelien.delobelle@gmail.com>
Date: Tue, 17 Oct 2017 14:41:53 +0200
Subject: [PATCH] Fix tirage pk conflicts with postgres

---
 bda/migrations/0002_add_tirage.py | 58 +++++++++++++++++++++++--------
 1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/bda/migrations/0002_add_tirage.py b/bda/migrations/0002_add_tirage.py
index 1956a4a4..22c387a0 100644
--- a/bda/migrations/0002_add_tirage.py
+++ b/bda/migrations/0002_add_tirage.py
@@ -5,17 +5,34 @@ from django.db import migrations, models
 from django.conf import settings
 from django.utils import timezone
 
-def forwards_func(apps, schema_editor):
+
+def fill_tirage_fields(apps, schema_editor):
+    """
+    Create a `Tirage` to fill new field `tirage` of `Participant`
+    and `Spectacle` already existing.
+    """
+    Participant = apps.get_model("bda", "Participant")
+    Spectacle = apps.get_model("bda", "Spectacle")
     Tirage = apps.get_model("bda", "Tirage")
-    db_alias = schema_editor.connection.alias
-    Tirage.objects.using(db_alias).bulk_create([
-        Tirage(
-            id=1,
-            title="Tirage de test (migration)",
-            active=False,
-            ouverture=timezone.now(),
-            fermeture=timezone.now()),
-    ])
+
+    # These querysets only contains instances not linked to any `Tirage`.
+    participants = Participant.objects.filter(tirage=None)
+    spectacles = Spectacle.objects.filter(tirage=None)
+
+    if not participants.count() and not spectacles.count():
+        # No need to create a "trash" tirage.
+        return
+
+    tirage = Tirage.objects.create(
+        title="Tirage de test (migration)",
+        active=False,
+        ouverture=timezone.now(),
+        fermeture=timezone.now(),
+    )
+
+    participants.update(tirage=tirage)
+    spectacles.update(tirage=tirage)
+
 
 class Migration(migrations.Migration):
 
@@ -35,22 +52,33 @@ class Migration(migrations.Migration):
                 ('active', models.BooleanField(default=True, verbose_name=b'Tirage actif')),
             ],
         ),
-        migrations.RunPython(forwards_func, migrations.RunPython.noop),
         migrations.AlterField(
             model_name='participant',
             name='user',
             field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
         ),
+        # Create fields `spectacle` for `Participant` and `Spectacle` models.
+        # These fields are not nullable, but we first create them as nullable
+        # to give a default value for existing instances of these models.
         migrations.AddField(
             model_name='participant',
             name='tirage',
-            field=models.ForeignKey(default=1, to='bda.Tirage'),
-            preserve_default=False,
+            field=models.ForeignKey(to='bda.Tirage', null=True),
         ),
         migrations.AddField(
             model_name='spectacle',
             name='tirage',
-            field=models.ForeignKey(default=1, to='bda.Tirage'),
-            preserve_default=False,
+            field=models.ForeignKey(to='bda.Tirage', null=True),
+        ),
+        migrations.RunPython(fill_tirage_fields, migrations.RunPython.noop),
+        migrations.AlterField(
+            model_name='participant',
+            name='tirage',
+            field=models.ForeignKey(to='bda.Tirage'),
+        ),
+        migrations.AlterField(
+            model_name='spectacle',
+            name='tirage',
+            field=models.ForeignKey(to='bda.Tirage'),
         ),
     ]