# Generated by Django 2.1 on 2018-08-31 13:17 import django.db.models.deletion from django.conf import settings from django.contrib.auth.models import Permission from django.db import migrations, models import openslides def create_comment_sections_from_config_and_move_comments_to_own_model( apps, schema_editor ): ConfigStore = apps.get_model("core", "ConfigStore") Motion = apps.get_model("motions", "Motion") MotionComment = apps.get_model("motions", "MotionComment") MotionCommentSection = apps.get_model("motions", "MotionCommentSection") Group = apps.get_model(settings.AUTH_GROUP_MODEL) # try to get old motions_comments config variable, where all comment fields are saved try: motions_comments = ConfigStore.objects.get(key="motions_comments") except ConfigStore.DoesNotExist: return comments_sections = motions_comments.value # Delete config value motions_comments.delete() # Get can_see_comments and can_manage_comments permissions and the associated groups can_see_comments = Permission.objects.filter(codename="can_see_comments") if len(can_see_comments) == 1: # Save groups. list() is necessary to evaluate the database query right now. can_see_groups = list(can_see_comments.get().group_set.all()) else: can_see_groups = Group.objects.all() can_manage_comments = Permission.objects.filter(codename="can_manage_comments") if len(can_manage_comments) == 1: # Save groups. list() is necessary to evaluate the database query right now. can_manage_groups = list(can_manage_comments.get().group_set.all()) else: can_manage_groups = Group.objects.all() # Create comment sections. Map them to the old ids, so we can find the right section # when creating actual comments old_id_mapping = {} # Keep track of the special comment sections "forState" and "forRecommendation". If a # comment is found, the comment value will be assigned to new motion fields and not comments. forStateId = None forRecommendationId = None for id, section in comments_sections.items(): if section is None: continue if section.get("forState", False): forStateId = id elif section.get("forRecommendation", False): forRecommendationId = id else: comment_section = MotionCommentSection(name=section["name"]) comment_section.save(skip_autoupdate=True) comment_section.read_groups.add(*[group.id for group in can_see_groups]) comment_section.write_groups.add(*[group.id for group in can_manage_groups]) old_id_mapping[id] = comment_section # Create all comments objects comments = [] for motion in Motion.objects.all(): if not isinstance(motion.comments, dict): continue for section_id, comment_value in motion.comments.items(): # Skip empty sections. comment_value = comment_value.strip() if comment_value == "": continue # Special comments will be moved to separate fields. if section_id == forStateId: motion.state_extension = comment_value motion.save(skip_autoupdate=True) elif section_id == forRecommendationId: motion.recommendation_extension = comment_value motion.save(skip_autoupdate=True) else: comment = MotionComment( comment=comment_value, motion=motion, section=old_id_mapping[section_id], ) comments.append(comment) MotionComment.objects.bulk_create(comments) class Migration(migrations.Migration): dependencies = [("users", "0006_user_email"), ("motions", "0011_motion_version_4")] operations = [ # Add extension fields for former "special comments". No hack anymore.. migrations.AddField( model_name="motion", name="recommendation_extension", field=models.TextField(blank=True, null=True), ), migrations.AddField( model_name="motion", name="state_extension", field=models.TextField(blank=True, null=True), ), migrations.AlterModelOptions( name="motion", options={ "default_permissions": (), "ordering": ("identifier",), "permissions": ( ("can_see", "Can see motions"), ("can_create", "Can create motions"), ("can_support", "Can support motions"), ("can_manage", "Can manage motions"), ), "verbose_name": "Motion", }, ), # Comments and CommentsSection models migrations.CreateModel( name="MotionComment", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ("comment", models.TextField()), ], options={"default_permissions": ()}, bases=( openslides.utils.models.RESTModelMixin, # type: ignore models.Model, ), ), migrations.CreateModel( name="MotionCommentSection", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ("name", models.CharField(max_length=255)), ( "read_groups", models.ManyToManyField( blank=True, related_name="read_comments", to=settings.AUTH_GROUP_MODEL, ), ), ( "write_groups", models.ManyToManyField( blank=True, related_name="write_comments", to=settings.AUTH_GROUP_MODEL, ), ), ], options={"default_permissions": ()}, bases=( openslides.utils.models.RESTModelMixin, # type: ignore models.Model, ), ), migrations.AddField( model_name="motioncomment", name="section", field=models.ForeignKey( on_delete=django.db.models.deletion.PROTECT, related_name="comments", to="motions.MotionCommentSection", ), ), migrations.AddField( model_name="motioncomment", name="motion", field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to="motions.Motion" ), ), migrations.AlterUniqueTogether( name="motioncomment", unique_together={("motion", "section")} ), # Move the comments and sections migrations.RunPython( create_comment_sections_from_config_and_move_comments_to_own_model ), # Remove old comment field from motion, use the new model instead migrations.RemoveField(model_name="motion", name="comments"), migrations.AlterField( model_name="motioncomment", name="motion", field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="comments", to="motions.Motion", ), ), ]