Reputation: 21
I am using Django CMS Frontend. I want to customize the plugins. For example, I want to add extra fields to the default Card plugin. I tried using Plugin Form
So far I have done this.
cms_plugins.py
class CustomPlugin(CMSPluginBase):
form = CardForm
name = "Custom Card"
render_template = "siteindex/card_render.html"
change_form_template = "siteindex/card.html"
cache = False
def render(self, context, instance, placeholder):
context = super().render(context, instance, placeholder)
return context
plugin_pool.register_plugin(CustomPlugin)
cms_forms.py
from djangocms_frontend.contrib.card.forms import CardForm
from django.db import models
class CustomForm(CardForm):
title = forms.CharField(max_length=255, required=False, label="title")
class Meta:
model = CustomCard
fields = "__all__"
card.html
{% extends "admin/cms/page/plugin/change_form.html" %}
card_render.html
{{ instance.title }}}
After that when I try to add a plugin I get this error (https://i.sstatic.net/2f7fjFSM.png)
Upvotes: 1
Views: 105
Reputation: 21
I solved it by adding the title to the untangled_fields on the CustomForm.
cms_plugins.py
@plugin_pool.register_plugin
class CustomCardPlugin(CardPlugin):
model = CustomCard
render_template = "siteindex/card_render.html"
change_form_template = "admin/custom_card/change_form.html"
name = "Custom Card"
form = CustomCardForm
fieldsets = [
(
None,
{
"fields": (
"title",
"card_alignment",
(
"card_text_color",
"card_outline",
),
"card_full_height",
),
},
),
]
def save_model(self, request, obj, form, change):
if form.is_valid():
title = form.cleaned_data.get("title")
obj.title = title
print(obj.__dict__)
super().save_model(request, obj, form, change)
cms_models.py
class CustomCard(Card):
title = models.CharField(max_length=255, blank=True, null=True)
cms_forms.py
class CustomCardForm(CardForm):
title = forms.CharField(max_length=255, required=True)
def clean(self):
super().clean()
class Meta:
model = CustomCard
exclude = []
untangled_fields = [
"title",
]
entangled_fields = {
"config": [
"card_alignment",
"card_outline",
"card_text_color",
"card_full_height",
"attributes",
]
}
card_render.html
<div class="bg-{{instance.background_context}} {{instance.margin_x}} {{instance.margin_y}}">
<h3 class="text-{{instance.card_text_color}}">{{ instance.title }}</h3>
<div class="card-content">
<div class="layout-{{ instance.layout }}">
<div class="card-type-{{ instance.card_type }}">
<div class="text-alignment-{{ instance.text_alignment }}">
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 850
You attach a djangocms-frontend card form to your custom plugin that does not have the fields of the djangocms-frontend card plugins. Hence the error.
djangocms-frontend plugins are extensible as described in its documentation by using Mixins. This would allow you to extend the existing card plugin.
If you want to create your own card plugin, try subclassing
djangocms_frontend.contrib.cms_plugins.CardPlugin
for updating the fieldsets and the render templatedjangocms_frontend.contrib.forms.CardForm
Note that the forms use the django-entangled package which means you'll have to do something like:
from djangocms_frontend.contrib.card.forms import CardForm
class CustomForm(CardForm):
title = forms.CharField(max_length=255, required=False, label="title")
class Meta:
entangled_fields = {
"config": [
"title",
]
}
No need for any changes in the model. The entangled form stores the additional title field in a JSON field in "config".
Hope this helps. Let me know how you succeed.
Upvotes: 1