【问题标题】:Django-CMS CMSPlugin doesn't trigger pre_save/post_save signalsDjango-CMS CMSPlugin 不会触发 pre_save/post_save 信号
【发布时间】:2018-08-09 22:02:40
【问题描述】:

我正在尝试将 Django-CMS 占位符的内容添加到搜索索引中(使用 Algolia,但我想这可能适用于任何索引服务,如 Elasticsearch 或类似服务)一旦更新。

使用 Django 1.10,django-cms 3.42,我有这个模型(针对这个问题进行了简化):

from django.db import models
from cms.models.fields import PlaceholderField
from cms.models import CMSPlugin

class NewsItem(models.Model):
    title=models.CharField(_('title'), max_length=200),
    content = PlaceholderField('news_content')

我需要在保存模型字段“内容”后立即进行一些额外的处理,显然检查这一点的最佳方法是监视 CMSPlugin 模型。所以我使用 django.db.models.signals.post_save 寻找保存,如下所示:

@receiver(post_save, sender=CMSPlugin)
def test(sender, **kwargs):
    logger.info("Plugin saved.")

现在,问题是 post_save 没有像我想象的那样被触发。对于普通的 CMS 页面,我注意到 post_save 仅在页面发布时触发,但在 CMS 之外使用时没有明显的方法来发布占位符。

我找到的最接近的类似案例是Updating indexes on placeholderfields in real time with django/haystack/solr,但建议的解决方案不起作用。

我该如何解决这个问题?

谢谢!

【问题讨论】:

  • 我强烈建议不要监听由 cms 对象(如 CMSPlugin)发送的保存前或保存后信号。我们一直在从核心中删除所有这些。用例是什么?
  • @Paulo 我正在尝试捕获对占位符的更新,以便更新搜索索引。我(希望)在问题中澄清了这一点。谢谢!
  • 我本可以用它来解决 aldryn-forms#167,其中复制字段会使页面无法访问,而无需通过 python shell 删除插件。我知道可以通过添加验证来解决问题,以防止创建重复的 Field.name,但无法找到添加它的方法

标签: django django-cms


【解决方案1】:

我们在实现djangocms-algolia 包时也遇到了同样的搜索索引问题,因为占位符更新不会触发索引的更新。

对于 CMS 页面,我们使用了来自 cms.signals 模块 herepost_publishpost_unpublish

对于使用占位符的 cms 应用程序(例如 djangocms-blog),我们将侦听器附加到 post_placeholder_operation,但请注意,要使其正常工作,您的 ModelAdmin 需要从 PlaceholderAdminMixin 继承:

def update_news_index(sender, operation: str, language: str, **kwargs) -> None:
    placeholder: Optional[Placeholder] = None

    if operation in (ADD_PLUGIN, DELETE_PLUGIN, CHANGE_PLUGIN, CLEAR_PLACEHOLDER):
        placeholder = kwargs.get('placeholder')
    elif operation in (ADD_PLUGINS_FROM_PLACEHOLDER, PASTE_PLUGIN, PASTE_PLACEHOLDER):
        placeholder = kwargs.get('target_placeholder')
    elif operation in (MOVE_PLUGIN, CUT_PLUGIN):
        placeholder = kwargs.get('source_placeholder')
    else:
        pass

    if placeholder:
        post: Post = Post.objects.language(language_code=language).filter(content=placeholder).first()
        if post:
            post.save()


signals.post_placeholder_operation.connect(update_news_index, PostAdmin)
signals.post_placeholder_operation.connect(update_news_index, PageAdmin)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-16
    • 2017-04-26
    • 2014-03-16
    • 1970-01-01
    • 2012-01-29
    • 2021-04-09
    • 2011-12-22
    • 1970-01-01
    相关资源
    最近更新 更多