8000 Moved placeholders from Page to Title model by Aiky30 · Pull Request #6442 · django-cms/django-cms · GitHub
[go: up one dir, main page]

Skip to content

Moved placeholders from Page to Title model #6442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jul 12, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8000
Prev Previous commit
refactored migrations
  • Loading branch information
czpython committed Jul 12, 2018
commit 57b00f19e45f04efc56056700f41c44ad88c4cfa
5 changes: 5 additions & 0 deletions cms/migrations/0022_title_placeholders.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ class Migration(migrations.Migration):
name='placeholders',
field=models.ManyToManyField(editable=False, to='cms.Placeholder'),
),
migrations.AddField(
model_name='placeholder',
name='title_id',
field=models.PositiveSmallIntegerField(null=True),
),
]
113 changes: 76 additions & 37 deletions cms/migrations/0023_title_placeholders_data_migration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import warnings, os, sys
from collections import defaultdict
import warnings

from django.db import migrations, models

Expand Down Expand Up @@ -32,43 +32,82 @@


def forwards(apps, schema_editor):

Page = apps.get_model('cms', 'Page')
Plugin = apps.get_model('cms', 'CMSPlugin')

# 1. Create a placeholder for each language the page is tied to (title_set)
# 2. Move all plugins for each language into their respective placeholder
# 3. Clean away the existing placeholders

page_list = Page.objects.all().prefetch_related('title_set')

for page in page_list:
# Get all titles registered to the page
title_set = page.title_set.all()
# Get the pages placeholders
placeholders = page.placeholders.all()
# Add each placeholder on the page template to the title
for title in title_set:
# Get a list of the plugins attached to this placeholder for this language
for placeholder in placeholders:
# Get all of the plugins for this placeholder
placeholder_plugins = Plugin.objects.filter(placeholder_id=placeholder.pk, language=title.language)
# Clone the placeholder
placeholder.pk = None
placeholder.save()
# Create a link to the new placeholder
title.placeholders.add(placeholder)

# Move the plugins to the relevant / new title -> placeholder
for plugin in placeholder_plugins:
plugin.placeholder_id = placeholder.pk
plugin.save()

# TODO: Delete previous placeholders!! None should have any plugins
# TODO: Handle exceptions!!
#except Exception:
# warnings.warn(u'Placeholder migration failure.')
#raise os.sys.exit(u'Placeholder migration failure.')
Placeholder = apps.get_model('cms', 'Placeholder')
db_alias = schema_editor.connection.alias
cms_pages = (
Page
.objects
.using(db_alias)
.filter(placeholders__isnull=False)
.distinct()
.prefetch_related('placeholders', 'title_set')
)
new_placeholders = []
old_placeholder_ids = []

for page in cms_pages:
for title in page.title_set.all():
for placeholder in page.placeholders.all():
new_placeholder = Placeholder(
slot=placeholder.slot,
default_width=placeholder.default_width,
title_id=title.pk,
)
new_placeholders.append(new_placeholder)
old_placeholder_ids.append(placeholder.pk)

# Create all new placeholders
Placeholder.objects.using(db_alias).bulk_create(new_placeholders)

# Map out all new placeholders by title id
placeholders_by_title = defaultdict(list)
new_placeholder_lookup = (
Placeholder
.objects
.using(db_alias)
.filter(title_id__isnull=False)
)

for new_pl in new_placeholder_lookup.iterator():
placeholders_by_title[new_pl.title_id].append(new_pl)

for page in cms_pages:
for translation in page.title_set.all():
new_placeholders = placeholders_by_title[translation.pk]

for new_placeholder in new_placeholders:
# Move all plugins whose language matches
# the current translation and are hosted on the
# current placeholder slot to point to the new title placeholder.
Plugin.objects.filter(
language=translation.language,
placeholder__page=page,
placeholder__slot=new_placeholder.slot,
).update(placeholder_id=new_placeholder.pk)
# Attach the new placeholders to the title
translation.placeholders.set(new_placeholders)

# Gather the old placeholders
old_placeholders = (
Placeholder
.objects
.using(db_alias)
.filter(pk__in=old_placeholder_ids)
.annotate(plugin_count=models.Count('cmsplugin'))
)

if old_placeholders.filter(plugin_count__gt=0).exists():
warnings.warn(
"There's placeholders in your database "
"with plugins in a language that's not configured "
"These placeholders and its plugins are not in use and can be removed.",
UserWarning,
)

# Delete all old placeholders that have no plugins
old_placeholders.filter(plugin_count=0).delete()


class Migration(migrations.Migration):
Expand Down
4 changes: 4 additions & 0 deletions cms/migrations/0024_remove_page_placeholders.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ class Migration(migrations.Migration):
model_name='page',
name='placeholders',
),
migrations.RemoveField(
model_name='placeholder',
name='title_id',
),
]
0