首页 > 解决方案 > 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)

标签: pythondjangodjango-cms

解决方案


推荐阅读