python - django cms plugin - 编辑相关对象自动发布更改
问题描述
在编辑通过TabularInline
更改用于在页面上自动发布的相关对象时。编辑相关对象请求时通过管理页面。
在实时编辑页面上,当在 cms 插件中对相关对象进行更改时,请求会通过管理页面。然后,相关对象的更改会自动发布在页面上,而无需使用按钮在网站上发布更改。当通过管理页面保存相关对象时也会发生同样的情况。
楷模:
from cms.models.pluginmodel import CMSPlugin
from django.db import models
from django.utils.translation import ugettext_lazy as __
from djangocms_text_ckeditor.fields import HTMLField
from filer.fields.image import FilerImageField
from plugins.generic.cards.styles import (
CARD_OPTIONS,
HOVER,
MARGIN_SIZES,
CARD_SECTION_OPTIONS,
HEADER_SECTION_OPTIONS
)
from plugins.generic.global_choices import (
BUTTON_COLOR, LINK_TARGET, BACKGROUND_COLOR, BORDER_COLOR, LINK_COLOR,
)
from .utils import ChoiceArrayField, GridSystem
class Card(models.Model):
"""Generic card model that is compatible with the Bootstrap grid system."""
name = models.CharField(max_length=100)
size = models.ForeignKey(
GridSystem,
verbose_name=__('Card size'),
help_text=__(
'Specify card size for different resolutions using '
'grid system from Bootstrap.'
),
)
background = models.CharField(
verbose_name=__('Card background color'),
max_length=100,
choices=BACKGROUND_COLOR,
blank=True,
null=True,
help_text=__('Transparent by default.'),
)
hover = models.CharField(
verbose_name=__('Card hover effect'),
max_length=100,
choices=HOVER,
blank=True,
null=True,
help_text=__(
'Choose what should happen when card is pointed with a cursor.'
),
)
options = ChoiceArrayField(
models.CharField(max_length=100, choices=CARD_OPTIONS),
verbose_name=__('More options'),
blank=True,
null=True,
help_text=__(
'Hold down "Control", or "Command" on a Mac, '
'to select more than one.'
),
)
hubspot_portal_id = models.CharField(
max_length=128,
blank=True,
null=True,
help_text=__('Portal ID of form created in HubSpot.'),
)
hubspot_form_id = models.CharField(
max_length=128,
blank=True,
null=True,
help_text=__('Form ID of form created in HubSpot.'),
)
icon = FilerImageField(blank=True, null=True)
icon_link = models.CharField(
verbose_name=__('Icon Link'),
max_length=255,
blank=True,
null=True,
help_text=__(
'Slug of current page subpage or full url. '
'You can use "#" as a placeholder.'
),
)
title = HTMLField(blank=True, null=True)
description = HTMLField(blank=True, null=True)
link = models.CharField(
verbose_name=__('Link'),
max_length=255,
blank=True,
null=True,
help_text=__(
'Slug of current page subpage or full url. '
'You can use "#" as a placeholder.'
'If "Whole card is redirecting" is enabled whole card pointing'
'to this link.'
),
)
link_text = models.CharField(
max_length=100,
blank=True,
null=True,
default=__('Learn more'),
help_text=__(
'Will not appear if link was not provided.'
),
)
link_color = models.CharField(
max_length=100,
blank=True,
null=True,
choices=LINK_COLOR,
help_text=__('Type in color of link text.'),
)
button_color = models.CharField(
verbose_name=__('Button type.'),
max_length=100,
choices=BUTTON_COLOR,
blank=True,
null=True,
help_text=__(
'Transform link to look like button.'
),
)
button_target = models.CharField(
max_length=100,
verbose_name=__('Button target.'),
choices=LINK_TARGET,
default='_self',
help_text=__('Select target of link / button.'),
)
class Meta:
verbose_name = __('Card')
def __str__(self):
return self.name
@property
def columns(self):
return self.size.bootstrap()
@property
def effects(self):
"""Returns formatted CSS class names ready to place in html."""
options = self.options or []
return ' '.join(options + list(
filter(None, [self.background, self.hover])
))
class CardsModel(CMSPlugin):
"""Model for CardsPlugin."""
name = models.CharField(max_length=100)
title = HTMLField(blank=True, null=True)
description = HTMLField(blank=True, null=True)
background = models.CharField(
verbose_name=__('Section background color'),
max_length=100,
choices=BACKGROUND_COLOR,
blank=True,
null=True,
)
border = models.CharField(
verbose_name=__('Section border color'),
max_length=100,
choices=BORDER_COLOR,
blank=True,
null=True,
)
header_options = ChoiceArrayField(
models.CharField(max_length=100, choices=HEADER_SECTION_OPTIONS),
verbose_name=__('Header section options'),
blank=True,
null=True,
help_text=__(
'Hold down "Control", or "Command" on a Mac, '
'to select more than one.'
),
)
cards_options = ChoiceArrayField(
models.CharField(max_length=100, choices=CARD_SECTION_OPTIONS),
verbose_name=__('Card section options'),
blank=True,
null=True,
help_text=__(
'Hold down "Control", or "Command" on a Mac, '
'to select more than one.'
),
)
margin_top = models.CharField(
verbose_name=__('Custom margin on top of container.'),
choices=MARGIN_SIZES,
blank=True,
null=True,
max_length=100,
)
cards = models.ManyToManyField(
Card, related_name='card_section', through='CardCardsModel'
)
def __str__(self):
return self.name
def copy_relations(self, old_instance):
"""Copy objects from many-to-many relation during publishing."""
for card in old_instance.cards.order_by('cardcardsmodel__id'):
CardCardsModel.objects.create(
card=card, card_section=self,
)
class Meta:
verbose_name = __('CardsContainer')
class CardCardsModel(models.Model):
"""Model handling many-to-many relation of CardsModel with Card."""
card = models.ForeignKey(Card)
card_section = models.ForeignKey(CardsModel)
class Meta:
verbose_name = __('Card')
verbose_name_plural = __('Add or edit cards')
def __str__(self):
return self.card.name
插入:
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from django.contrib import admin
from django.utils.translation import ugettext_lazy as __
from .models.cards import Card, CardsModel
class CardsAdmin(admin.TabularInline):
model = Card.card_section.through
extra = 0
class CardsPlugin(CMSPluginBase):
model = CardsModel
name = __('Cards')
inlines = (CardsAdmin, )
render_template = 'cards.html'
exclude = ('cards', )
def render(self, context, instance, placeholder):
context = super().render(context, instance, placeholder)
context['section'] = instance
context['cards'] = instance.cards.order_by('cardcardsmodel__id')
return context
plugin_pool.register_plugin(CardsPlugin)
解决方案
推荐阅读
- android - 使用片段的不同方式
- amazon-cloudformation - CloudFormation 组合子 - 导入 - 子
- python - APScheduler 作业消失
- java - jDateChooser 的值恢复到默认值
- linkerd - linkerd:自动注入被忽略
- ios - 如何正确扩展 RxCocoa.Driver?
- linq - LINQ 查询在 Dot Net Core 2.2 但在 3.1 中工作正常
- java - JAXB / Java 11 / Tomcat - DataHandler 无默认构造函数
- java - 为什么相同算法在倍率测试中运行时间不同?
- java - 条件不检查。爪哇,AWT