Reputation: 2265
I have a custom plugin called MultiColumnResponsive that receives the number of columns as parameter and accepts ColumnResponsive plugin only as children. I want to create the ColumnResponsive plugins nested as children by default, but I am not able to do it.
Here my current code:
cms_plugins.py
class MultiColumnResponsivePlugin(CMSPluginBase):
name = "Multi Column Responsive"
module = _("Containers")
model = MultiColumn
render_template = "plugin/multi-column-responsive/multi-column-responsive.html"
allow_children = True
child_classes = ["ColumnResponsivePlugin"]
def render(self, context, instance, placeholder):
context = super(MultiColumnResponsivePlugin, self).render(context, instance, placeholder)
return context
class ColumnResponsivePlugin(CMSPluginBase):
name = "Column Responsive"
module = _("Containers")
render_template = "plugin/column-responsive/column-responsive.html"
allow_children = True
parent_classes = ["MultiColumnResponsivePlugin"]
def render(self, context, instance, placeholder):
context = super(ColumnResponsivePlugin, self).render(context, instance, placeholder)
return context
models.py
class MultiColumn(CMSPlugin):
NUM_OF_COLUMNS = (
(1, '1'),
(2, '2'),
)
num_of_columns = models.IntegerField(default=1, choices=NUM_OF_COLUMNS)
This is the desire result when I add a MultiColumnResponsive plugin with 2 columns:
EDIT: After several days digging into it. I achieved it adding a few lines in the save_model
function in the MultiColumnResponsivePlugin class:
def save_model(self, request, obj, form, change):
response = super(MultiColumnResponsivePlugin, self).save_model(
request, obj, form, change
)
for x in range(int(form.cleaned_data['num_of_columns'])):
add_plugin(obj.placeholder, ColumnResponsivePlugin.__name__, obj.language, target=obj)
return response
Upvotes: 1
Views: 543
Reputation: 1695
You can try this:
from django.forms import ModelForm, NumberInput
from cms.api import add_plugin
class MultiColumnResponsiveForm(ModelForm):
wanted_children = NumberInput()
class Meta:
model = MultiColumn
fields = '__all__'
class MultiColumnResponsivePlugin(CMSPluginBase):
name = "Multi Column Responsive"
module = _("Containers")
model = MultiColumn
render_template = "plugin/multi-column-responsive/multi-column-responsive.html"
allow_children = True
child_classes = ["ColumnResponsivePlugin"]
form = MultiColumnResponsiveForm
def save_model(self, request, obj, form, change):
wanted_children = form.cleaned_data['wanted_children']
super().save_model(request, obj, form, change)
self.extend_children(obj, wanted_children)
def extend_children(self, parent, wanted_children):
current_children = parent.get_num_children()
for _ in range(current_children, wanted_children):
child = add_plugin(parent.placeholder, ColumnResponsivePlugin,
parent.language, target=parent)
child.save()
Some notes on this:
If you need a temporary value such as wanted_children
, use a form and do not pollute your model!
This code snippet is an adoption from djangocms-cascade, which uses a similar approach to achieve the same result.
Upvotes: 2