Skip to content

Instantly share code, notes, and snippets.

@corentinbettiol
Last active June 16, 2023 08:55
Show Gist options
  • Save corentinbettiol/84a6ea7e4d047fc01861b0af15fd60f0 to your computer and use it in GitHub Desktop.
Save corentinbettiol/84a6ea7e4d047fc01861b0af15fd60f0 to your computer and use it in GitHub Desktop.
Migrate from cmsplugin_filer to djangocms_file, djangocms_folder, djangocms_link, djangocms_picture.

From cmsplugins to djangocms-<file|folder|link|picture>

migrate_cmsplugin_filer.py script must not be executed as is. You must adapt it for the project's need.

  1. Install and add/upgrade to your requirements:
  • django-filer==1.5.0
  • djangocms-file==2.3.0
  • djangocms-picture==2.3.0
  • djangocms-link==2.5.0
  1. Add those packages to INSTALLED_APPS:
    "djangocms_file",
    "djangocms_picture",
    "djangocms_link",
  2. Create a new DJANGOCMS_PICTURE_TEMPLATES settings matching the old CMSPLUGIN_FILER_IMAGE_STYLE_CHOICES.
  3. Create a new DJANGOCMS_FILE_TEMPLATES settings matching the old CMSPLUGIN_FILER_FOLDER_STYLE_CHOICES and CMSPLUGIN_FILER_FILE_STYLE_CHOICES.
  4. Create a new DJANGOCMS_LINK_TEMPLATES settings matching the old FILER_LINK_STYLES.
  5. Migrate database to create tables:
    $ django-admin migrate
  6. Copy the migrate_cmsplugin_filer.py management command in your /management/commands/ folder.
  7. Configure the DOMAIN_URL in migrate_cmsplugin_filer.py.
  8. Run the migrate_cmsplugin_filer.py management command:
    $ django-admin migrate_cmsplugin_filer
  9. Update CMS_PLACEHOLDER_CONF to replace FilerLinkPlugin, FilerFolderPlugin, FilerImagePlugin and FilerFilePlugin respectively with new LinkPlugin, FolderPlugin, PicturePlugin and FilePlugin
  10. Rewrite cmsplugin_filer html templates
  11. Commit, push and apply same instructions your production (< might need more details here)
  12. Remove those apps from INSTALLED_APPS:
    "cmsplugin_filer_link",
    "cmsplugin_filer_file",
    "cmsplugin_filer_folder",
    "cmsplugin_filer_image",
  13. Uninstall cmsplugin-filer from virtualenv and remove from requirements.
  14. Upgrade to django-filer>=1.6.0, update djangocms-<file|folder|link|picture> packages.
  15. Remove old cmsplugin templates
  16. Remove CMSPLUGIN_FILER_FOLDER_STYLE_CHOICES, CMSPLUGIN_FILER_IMAGE_STYLE_CHOICES, CMSPLUGIN_FILER_FILE_STYLE_CHOICES settings from your settings.py
  17. Update permissions of users for the new cms plugins: djangocms_file, djangocms_picture and djangocms_link. 19.Its mostly done! See if you can spot some problems.

Although this is a secret gist, this code is open source so you're free to use or update it, share it, and to do whatever you want. You can credit Kapt, but it's not mandatory. We're not responsible if anything goes wrong if you use this management command, use it at your own risk.

# -*- coding:utf-8 -*-
# Standard library imports
from __future__ import unicode_literals
from django.core.management.base import BaseCommand
from django.db import transaction
from djangocms_picture.models import get_templates as get_picture_templates
from djangocms_file.models import get_templates as get_file_templates
from djangocms_link.models import get_templates as get_link_templates
from django.db import connection
from django.db.migrations.recorder import MigrationRecorder
DOMAIN_URL = "SET THIS TO YOUR DOMAIN URL"
try:
from cmsplugin_filer_file.models import FilerFile as CMSPluginFilerFile
from djangocms_file.models import File as DjangoCMSFileFile
except ImportError:
print("Warning: Cant import cmsplugin_filer_file or djangocms_file models")
CMSPluginFilerFile = None
DjangoCMSFileFile = None
try:
from cmsplugin_filer_folder.models import FilerFolder as CMSPluginFilerFolder
from djangocms_file.models import Folder as DjangoCMSFileFolder
except ImportError:
print("Warning: Cant import cmsplugin_filer_folder or djangocms_file models")
CMSPluginFilerFolder = None
DjangoCMSFileFolder = None
try:
from cmsplugin_filer_image.models import FilerImage as CMSPluginFilerImage
from djangocms_picture.models import Picture as DjangoCMSPicture
except ImportError:
print("Warning: Cant import cmsplugin_filer_image or djangocms_picture models")
CMSPluginFilerImage = None
DjangoCMSPicture = None
try:
from cmsplugin_filer_link.models import FilerLinkPlugin as CMSPluginFilerLink
from djangocms_link.models import Link as DjangoCMSLink
except ImportError:
print("Warning: Cant import cmsplugin_filer_link or djangocms_link models")
CMSPluginFilerLink = None
DjangoCMSLink = None
class Command(BaseCommand):
args = "<directory>"
help = "Migrate from cmsplugin_filer to djangocms_file, djangocms_folder, djangocms_picture."
def handle(self, *args, **options):
with transaction.atomic():
self.forwards_filer_file()
self.forwards_filer_folder()
self.forwards_filer_image()
self.forwards_filer_link()
self.delete_old_tables()
self.delete_old_migrations()
def forwards_filer_file(self):
print("Processing filer file")
if CMSPluginFilerFile:
for old_object in CMSPluginFilerFile.objects.all():
default_template = get_file_templates()[0][0]
print(
"Processing plugin {}, inheriting from CMSPLugin {}".format(
old_object.id, old_object.cmsplugin_ptr
)
)
old_cmsplugin_ptr = old_object.cmsplugin_ptr
old_object
old_cmsplugin_ptr.plugin_type = "FilePlugin"
old_cmsplugin_ptr.save()
new_object = DjangoCMSFileFile(
cmsplugin_ptr_id=old_cmsplugin_ptr.id,
file_name=old_object.title or "",
file_src=old_object.file,
link_target="_blank" if old_object.target_blank else "",
link_title=old_object.title or "",
template=old_object.style or default_template,
attributes=old_object.link_attributes,
# defaults for fields that don't exist in the old_object
show_file_size=False,
# fields for the cms_cmsplugin table
plugin_type="FilePlugin",
position=old_cmsplugin_ptr.position,
language=old_cmsplugin_ptr.language,
creation_date=old_cmsplugin_ptr.creation_date,
changed_date=old_cmsplugin_ptr.changed_date,
parent=old_cmsplugin_ptr.parent,
placeholder=old_cmsplugin_ptr.placeholder,
depth=old_cmsplugin_ptr.depth,
numchild=old_cmsplugin_ptr.numchild,
path=old_cmsplugin_ptr.path,
)
new_object.save()
print(
"Created new plungin {}, with parent {}".format(
new_object.id, new_object.cmsplugin_ptr.id
)
)
def forwards_filer_folder(self):
print("Processing filer folder")
if CMSPluginFilerFolder:
default_template = get_file_templates()[0][0]
for old_object in CMSPluginFilerFolder.objects.all():
print(
"Processing plugin {}, inheriting from CMSPLugin {}".format(
old_object.id, old_object.cmsplugin_ptr
)
)
old_cmsplugin_ptr = old_object.cmsplugin_ptr
old_cmsplugin_ptr.plugin_type = "FolderPlugin"
old_cmsplugin_ptr.save()
# Props lost from old object:
# - title
new_object = DjangoCMSFileFolder(
cmsplugin_ptr_id=old_cmsplugin_ptr.id,
folder_src=old_object.folder,
template=old_object.style or default_template,
# defaults for fields that don't exist in the old_object
link_target="",
show_file_size=False,
# fields for the cms_cmsplugin table
plugin_type="FolderPlugin",
position=old_cmsplugin_ptr.position,
language=old_cmsplugin_ptr.language,
creation_date=old_cmsplugin_ptr.creation_date,
changed_date=old_cmsplugin_ptr.changed_date,
parent=old_cmsplugin_ptr.parent,
placeholder=old_cmsplugin_ptr.placeholder,
depth=old_cmsplugin_ptr.depth,
numchild=old_cmsplugin_ptr.numchild,
path=old_cmsplugin_ptr.path,
)
new_object.save()
print(
"Created new plungin {}, with parent {}".format(
new_object.id, new_object.cmsplugin_ptr.id
)
)
def forwards_filer_image(self):
print("Processing filer images")
if CMSPluginFilerImage:
default_template = get_picture_templates()[0][0]
for old_object in CMSPluginFilerImage.objects.all():
print(
"Processing plugin {}, inheriting from CMSPLugin {}".format(
old_object.id, old_object.cmsplugin_ptr
)
)
old_cmsplugin_ptr = old_object.cmsplugin_ptr
old_object
old_cmsplugin_ptr.plugin_type = "PicturePlugin"
old_cmsplugin_ptr.save()
attributes = {}
if old_object.alt_text:
attributes.update({"alt": old_object.alt_text})
if old_object.thumbnail_option is not None:
use_crop = False
use_upscale = False
else:
use_crop = old_object.crop
use_upscale = old_object.upscale
width = old_object.width
height = old_object.height
if (
old_object.image
and old_object.image.width
and old_object.image.height
):
if not height and width:
height = int(
width * old_object.image.height / old_object.image.width
)
elif not width and height:
width = int(
height * old_object.image.width / old_object.image.height
)
# Props lost from old object:
# - original_link -> OK
# - description -> OK
# - file_link_id : recreate links to files by hand (don't remember what this comment is all about :/)
new_object = DjangoCMSPicture(
cmsplugin_ptr_id=old_cmsplugin_ptr.id,
caption_text=old_object.caption_text,
external_picture=old_object.image_url or "",
use_automatic_scaling=old_object.use_autoscale,
width=width,
height=height,
use_crop=use_crop,
use_upscale=use_upscale,
alignment=old_object.alignment or "",
picture=old_object.image,
thumbnail_options=old_object.thumbnail_option,
attributes=attributes,
link_url=old_object.free_link,
link_page_id=old_object.page_link_id,
link_attributes=old_object.link_attributes,
use_no_cropping=old_object.use_original_image,
template=old_object.style or default_template,
# fields for the cms_cmsplugin table
plugin_type="PicturePlugin",
position=old_cmsplugin_ptr.position,
language=old_cmsplugin_ptr.language,
creation_date=old_cmsplugin_ptr.creation_date,
changed_date=old_cmsplugin_ptr.changed_date,
parent=old_cmsplugin_ptr.parent,
placeholder=old_cmsplugin_ptr.placeholder,
depth=old_cmsplugin_ptr.depth,
numchild=old_cmsplugin_ptr.numchild,
path=old_cmsplugin_ptr.path,
)
if old_object.target_blank:
new_object.link_target = "_blank"
new_object.save()
print(
"Created new plungin {}, with parent {}".format(
new_object.id, new_object.cmsplugin_ptr.id
)
)
def forwards_filer_link(self):
print("Processing filer links")
if CMSPluginFilerLink:
default_template = get_link_templates()[0][0]
for old_object in CMSPluginFilerLink.objects.all():
print(
"Processing plugin {}, inheriting from CMSPLugin {}".format(
old_object.id, old_object.cmsplugin_ptr
)
)
old_cmsplugin_ptr = old_object.cmsplugin_ptr
old_object
old_cmsplugin_ptr.plugin_type = "LinkPlugin"
old_cmsplugin_ptr.save()
external_link = ""
if old_object.url not in [None, ""]:
external_link = old_object.url
if external_link.startswith("/"):
external_link = DOMAIN_URL + external_link
new_object = DjangoCMSLink(
cmsplugin_ptr_id=old_cmsplugin_ptr.id,
template=old_object.link_style.strip() or default_template,
name=old_object.name,
external_link=external_link,
internal_link_id=old_object.page_link_id,
file_link_id=old_object.file_id,
mailto=old_object.mailto or "",
attributes=old_object.link_attributes,
# defaults for fields that don't exist in the old_object
anchor="",
phone="",
# fields for the cms_cmsplugin table
plugin_type="LinkPlugin",
position=old_cmsplugin_ptr.position,
language=old_cmsplugin_ptr.language,
creation_date=old_cmsplugin_ptr.creation_date,
changed_date=old_cmsplugin_ptr.changed_date,
parent=old_cmsplugin_ptr.parent,
placeholder=old_cmsplugin_ptr.placeholder,
depth=old_cmsplugin_ptr.depth,
numchild=old_cmsplugin_ptr.numchild,
path=old_cmsplugin_ptr.path,
)
if old_object.new_window:
new_object.target = "_blank"
new_object.save()
print(
"Created new plungin {}, with parent {}".format(
new_object.id, new_object.cmsplugin_ptr.id
)
)
def delete_old_tables(self):
old_tables = [
"cmsplugin_filer_file_filerfile",
"cmsplugin_filer_folder_filerfolder",
"cmsplugin_filer_image_filerimage",
"cmsplugin_filer_video_filervideo",
"cmsplugin_filerfile",
"cmsplugin_filerfolder",
"cmsplugin_filerimage",
]
cursor = connection.cursor()
for old_table in old_tables:
cursor.execute("DROP TABLE IF EXISTS {}".format(old_table))
def delete_old_migrations(self):
old_apps = [
"cmsplugin_filer_folder",
"cmsplugin_filer_video",
"cmsplugin_filer_image",
"cmsplugin_filer_file",
]
MigrationRecorder.Migration.objects.filter(app__in=old_apps).delete()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment