OpenSlides/openslides/motions/migrations/0012_motion_comments.py

216 lines
7.9 KiB
Python

# 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",
),
),
]