# Generated by Django 5.2.3 on 2025-06-21 21:59 import django.db.models.deletion from django.conf import settings from django.db import migrations, models from django.db.migrations.state import StateApps from django.db.models import Case, When PRESIDENT_ROLE = 10 SITH_CLUB_ROLES = { 10: "Président⸱e", 9: "Vice-Président⸱e", 7: "Trésorier⸱e", 5: "Responsable communication", 4: "Secrétaire", 3: "Responsable info", 2: "Membre du bureau", 1: "Membre actif⸱ve", 0: "Curieux⸱euse", } def migrate_roles(apps: StateApps, schema_editor): ClubRole = apps.get_model("club", "ClubRole") Membership = apps.get_model("club", "Membership") updates = [] for club_id, role in Membership.objects.values_list("club", "role").distinct(): new_role = ClubRole.objects.create( name=SITH_CLUB_ROLES[role], is_board=role > settings.SITH_MAXIMUM_FREE_ROLE, is_presidency=role == PRESIDENT_ROLE, club_id=club_id, order=PRESIDENT_ROLE - role, ) updates.append(When(role=role, then=new_role.id)) # all updates must happen at the same time # otherwise, the 10 first created ClubRole would be # re-modified after their initial creation, and it would # result in an incoherent state. # To avoid that, all updates are wrapped in a single giant Case(When) statement # cf. https://docs.djangoproject.com/fr/stable/ref/models/conditional-expressions/#conditional-update Membership.objects.update(role=Case(*updates)) class Migration(migrations.Migration): dependencies = [ ("club", "0014_alter_club_options_rename_unix_name_club_slug_name_and_more"), ("core", "0047_alter_notification_date_alter_notification_type"), ] operations = [ migrations.AlterField( model_name="club", name="page", field=models.OneToOneField( blank=True, on_delete=django.db.models.deletion.PROTECT, related_name="club", to="core.page", ), ), migrations.CreateModel( name="ClubRole", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "order", models.PositiveIntegerField( db_index=True, editable=False, verbose_name="order" ), ), ( "club", models.ForeignKey( help_text="The club with which this role is associated", on_delete=django.db.models.deletion.CASCADE, related_name="roles", to="club.club", verbose_name="club", ), ), ("name", models.CharField(max_length=50, verbose_name="name")), ( "description", models.TextField( default="", blank=True, verbose_name="description" ), ), ( "is_board", models.BooleanField(default=False, verbose_name="Board role"), ), ( "is_presidency", models.BooleanField(default=False, verbose_name="Presidency role"), ), ( "is_active", models.BooleanField( default=True, help_text=( "If the role is inactive, people joining the club " "won't be able to get it." ), verbose_name="is active", ), ), ], options={ "ordering": ("order",), "verbose_name": "club role", "verbose_name_plural": "club roles", }, ), migrations.AddConstraint( model_name="clubrole", constraint=models.CheckConstraint( condition=models.Q( ("is_presidency", False), ("is_board", True), _connector="OR" ), name="clubrole_presidency_implies_board", ), ), migrations.RunPython(migrate_roles, migrations.RunPython.noop), # because Postgres migrations run in a single transaction, # we cannot change the actual values of Membership.role # and apply the FOREIGN KEY constraint in the same migration. # The constraint is created in the next migration ]