101 lines
3.5 KiB
Python
101 lines
3.5 KiB
Python
import json
|
|
from optparse import make_option
|
|
from django.core.management.base import BaseCommand
|
|
from django.core.serializers.json import DjangoJSONEncoder
|
|
|
|
from cms.models import Page, CMSPlugin, Placeholder, Title
|
|
from cms.models.managers import PageManager
|
|
from django.core import serializers
|
|
|
|
exclude_attrs = {'Page': ('site', 'id'),
|
|
'Placeholder': ('id', ),
|
|
'CMSPlugin': (),
|
|
'Title': (),
|
|
}
|
|
|
|
def title_natural_key(self):
|
|
return (self.path, )
|
|
|
|
def placeholder_natural_key(self):
|
|
return self.page.natural_key() + (self.slot, )
|
|
|
|
def plugin_natural_key(self):
|
|
return self.placeholder.natural_key() + (self.plugin_type, self.position)
|
|
|
|
Title.natural_key = title_natural_key
|
|
Placeholder.natural_key = placeholder_natural_key
|
|
CMSPlugin.natural_key = plugin_natural_key
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Dumps CMS page and its content(if required)'
|
|
args = 'output.json'
|
|
|
|
option_list = BaseCommand.option_list + (
|
|
make_option('--page', action='store', default=1),
|
|
make_option('--lang', action='store', default='fr'),
|
|
make_option('--output', action='store', default='dump.json')
|
|
)
|
|
|
|
def _serialize(self, data):
|
|
model_name = data.__class__.__name__
|
|
model_fields = [field[0].name for field in data._meta.get_fields_with_model()]
|
|
if exclude_attrs.get(model_name):
|
|
fields = set(model_fields) - set(exclude_attrs[model_name])
|
|
else:
|
|
fields = set(model_fields)
|
|
return serializers.serialize('python', (data,), use_natural_keys=True, fields=fields)
|
|
|
|
def _serialize_plugin(self, plugin):
|
|
instance, model = plugin.get_plugin_instance()
|
|
data = self._serialize(instance)
|
|
data[0]['fields'].update(self._serialize(plugin)[0]['fields'])
|
|
return data
|
|
|
|
def serialize_page(self, page):
|
|
"""
|
|
serialize the page and its title
|
|
"""
|
|
title = page.title_set.get(language=self.options['lang'])
|
|
placeholders = page.placeholders.all()
|
|
data = self._serialize(page) + self._serialize(title) + self.serialize_placeholders(placeholders)
|
|
for child in page.children.all():
|
|
data += self.serialize_page(child)
|
|
return data
|
|
|
|
def serialize_placeholders(self, placeholders):
|
|
"""
|
|
serialize placeholders and their attached plugins
|
|
"""
|
|
data = []
|
|
|
|
for placeholder in placeholders:
|
|
[serialized_placeholder] = self._serialize(placeholder)
|
|
serialized_placeholder['fields']['page'] = placeholder.page.natural_key()
|
|
data += [serialized_placeholder] + self.serialize_cmsplugins(placeholder.cmsplugin_set.all())
|
|
return data
|
|
|
|
def serialize_cmsplugins(self, plugins):
|
|
"""
|
|
serialize plugins and sub plugins
|
|
"""
|
|
data = []
|
|
for plugin in plugins:
|
|
# data += self._serialize_plugin(plugin)
|
|
data += self._serialize_plugin(plugin) + self.serialize_cmsplugins(plugin.cmsplugin_set.filter(parent__isnull=True))
|
|
return data
|
|
|
|
def handle(self, *args, **options):
|
|
|
|
def page_natural_key(self):
|
|
path = self.get_path(options['lang'])
|
|
if path:
|
|
return (path, )
|
|
|
|
Page.natural_key = page_natural_key
|
|
|
|
self.options = options
|
|
page = Page.objects.get(pk=options['page'])
|
|
with open(options.get('output'), 'w') as output:
|
|
json.dump(self.serialize_page(page), output, cls=DjangoJSONEncoder)
|