You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django CMS插件关联对象编辑自动发布功能实现咨询

Hey there! Let's work through your problem—you want all edits to related objects (whether via TabularInline, CMS plugin edit views, or the admin) to route through the Admin interface, and have those changes auto-publish to the front end without needing manual site publish clicks. Here's a step-by-step solution tailored to Django CMS and Django Admin:

First, we need to make sure any attempt to edit related objects redirects or links directly to the Admin, instead of using custom CMS plugin forms.

For TabularInline (Admin Native)

TabularInline is already an Admin component, so edits here will naturally use the Admin flow. Just ensure your Inline is properly configured in your parent model's Admin class:

from django.contrib import admin
from .models import ParentModel, RelatedModel

class RelatedModelInline(admin.TabularInline):
    model = RelatedModel
    extra = 1

class ParentModelAdmin(admin.ModelAdmin):
    inlines = [RelatedModelInline]

admin.site.register(ParentModel, ParentModelAdmin)

For CMS Plugin Edit Views

Replace any inline edit forms in your CMS plugin's edit popup with links to the Admin. First, update your plugin to pass related objects to the template:

from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from .models import MyPluginModel
from django.utils.translation import gettext_lazy as _

class MyPlugin(CMSPluginBase):
    model = MyPluginModel
    name = _("My Custom Plugin")
    render_template = "myapp/plugin.html"
    change_form_template = "myapp/plugin_edit.html" # Custom edit template

    def render_edit(self, context, instance, placeholder):
        context['related_objects'] = instance.related_objects.all()
        return super().render_edit(context, instance, placeholder)

Then create the custom edit template (myapp/plugin_edit.html) with Admin links:

{% extends "cms/plugins/edit.html" %}
{% block plugin_content %}
    <h3>Related Objects</h3>
    {% for obj in related_objects %}
        <div>
            {{ obj.title }} 
            <a href="{% url 'admin:myapp_relatedmodel_change' obj.id %}" target="_blank">Edit in Admin</a>
        </div>
    {% empty %}
        <p>No related objects yet. <a href="{% url 'admin:myapp_relatedmodel_add' %}?page={{ placeholder.page.id }}" target="_blank">Add New in Admin</a></p>
    {% endfor %}
{% endblock %}

This forces users to edit related objects directly in the Admin, ensuring all requests follow the Admin workflow.

2. Auto-Publish Changes to the Front End

To auto-publish after saving related objects, we'll use Django signals (or override Admin save methods) to trigger page publishing whenever a related object is updated.

Option 1: Use Django Signals (Global Trigger)

Create a post_save signal that finds all CMS pages using the modified related object and publishes them:

from django.db.models.signals import post_save
from django.dispatch import receiver
from cms.models import Page, CMSPlugin
from .models import RelatedModel, MyPluginModel

@receiver(post_save, sender=RelatedModel)
def auto_publish_related_changes(sender, instance, **kwargs):
    # Find all plugin instances linked to the modified related object
    plugin_instances = MyPluginModel.objects.filter(related_objects=instance)
    
    for plugin in plugin_instances:
        cms_plugin = plugin.cmsplugin_ptr
        page = cms_plugin.placeholder.page
        
        # Publish the page if it has a draft version
        if page and page.publisher_is_draft:
            page.publish(user=None) # Pass a user object if you need audit logs

Option 2: Override Admin Save Method (Admin-Only Trigger)

If you only want auto-publish when edits happen via the Admin, override the save_model method in your RelatedModel's Admin class:

from django.contrib import admin
from .models import RelatedModel

class RelatedModelAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        super().save_model(request, obj, form, change)
        # Reuse the publish logic from the signal above
        plugin_instances = MyPluginModel.objects.filter(related_objects=obj)
        for plugin in plugin_instances:
            page = plugin.cmsplugin_ptr.placeholder.page
            if page and page.publisher_is_draft:
                page.publish(user=request.user) # Use the current admin user for logs

admin.site.register(RelatedModel, RelatedModelAdmin)
3. Edge Cases to Handle
  • Permissions: Ensure users have both change permissions for the related model and publish permissions for CMS pages.
  • Bulk Edits: For bulk edits in the Admin, add a custom action to trigger publishing for all modified objects.
  • Performance: If a related object is used on many pages, use async tasks (like Celery) to handle publishing in the background and avoid blocking the Admin interface.
  • Draft/Live Sync: Add checks to skip publishing if the page's draft and live versions are already identical.

内容的提问来源于stack exchange,提问作者Lukasz Jagodzinski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:48:45