from datetime import timedelta import django.db.models.deletion import django.utils.timezone from django.db import migrations, models def copy_group_boards_to_memberships(apps, schema_editor): group_model = apps.get_model("tasks", "TaskBoardGroup") membership_model = apps.get_model("tasks", "TaskBoardGroupMembership") old_through = group_model.boards.through base_time = django.utils.timezone.now() positions = {} memberships = [] for link in old_through.objects.order_by( "taskboardgroup_id", "id", ).iterator(): group_id = link.taskboardgroup_id positions[group_id] = positions.get(group_id, 0) + 1 memberships.append( membership_model( group_id=group_id, board_id=link.taskboard_id, position=positions[group_id], added_at=base_time + timedelta(microseconds=link.id), ) ) membership_model.objects.bulk_create(memberships) def restore_implicit_group_boards(apps, schema_editor): group_model = apps.get_model("tasks", "TaskBoardGroup") membership_model = apps.get_model("tasks", "TaskBoardGroupMembership") old_through = group_model.boards.through old_through.objects.bulk_create( [ old_through( taskboardgroup_id=membership.group_id, taskboard_id=membership.board_id, ) for membership in membership_model.objects.order_by( "group_id", "position", "id", ).iterator() ], ignore_conflicts=True, ) class Migration(migrations.Migration): dependencies = [ ("tasks", "0037_shared_task_board_groups"), ] operations = [ migrations.CreateModel( name="TaskBoardGroupMembership", fields=[ ( "id", models.BigAutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ("position", models.PositiveIntegerField(verbose_name="Позиция")), ( "added_at", models.DateTimeField( default=django.utils.timezone.now, verbose_name="Добавлено", ), ), ( "board", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="group_memberships", to="tasks.taskboard", verbose_name="Доска", ), ), ( "group", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="board_memberships", to="tasks.taskboardgroup", verbose_name="Группа", ), ), ], options={ "verbose_name": "Доска в группе", "verbose_name_plural": "Доски в группах", "ordering": ["group_id", "position", "id"], "constraints": [ models.UniqueConstraint( fields=("group", "board"), name="uniq_task_board_group_membership", ), models.UniqueConstraint( fields=("group", "position"), name="uniq_task_board_group_position", ), ], }, ), migrations.RunPython( copy_group_boards_to_memberships, restore_implicit_group_boards, ), migrations.RemoveField( model_name="taskboardgroup", name="boards", ), migrations.AddField( model_name="taskboardgroup", name="boards", field=models.ManyToManyField( blank=True, related_name="board_groups", through="tasks.TaskBoardGroupMembership", to="tasks.taskboard", verbose_name="Доски", ), ), migrations.AlterField( model_name="taskboardgroupmembership", name="added_at", field=models.DateTimeField(auto_now_add=True, verbose_name="Добавлено"), ), ]