如何在django-cms 4.1.1中正确将模型字段转换为占位符字段(替代已废弃的PlaceholderField)
嘿,我来帮你搞定django-cms 4.1.1里替换废弃的PlaceholderField的问题!你说得没错,PlaceholderField在4.x版本里确实被弃用了,现在要用PlaceholderRelationField来实现相同的功能,而且灵活性更高,下面是一步步的具体操作:
1. 调整模型文件(models.py)
首先你得把原来的body TextField字段删掉——咱们要用占位符替代它了。同时一定要保留PlaceholderRelationField,它是模型和多个占位符之间的关联桥梁,一个模型可以绑定好几个不同的占位符slot(比如body、侧边栏之类的)。
然后加个缓存属性,方便快速获取对应"body" slot的占位符,加create=True的话,要是这个占位符还不存在会自动创建,省得你手动去生成:
from django.db import models from django.utils.translation import gettext_lazy as _ from django.core.cache import cached_property from cms.models.fields import PlaceholderRelationField from cms.utils.placeholder import get_placeholder_from_slot class Meeting(models.Model): # 保留你原来的其他字段:start_date、location、title、slug这些 # --- 把原来的body TextField删掉 --- # body = models.TextField(_('body'), default='', blank=True) placeholders = PlaceholderRelationField() @cached_property def body_placeholder(self): # 获取名为"body"的占位符,不存在就自动创建 return get_placeholder_from_slot(self.placeholders, "body", create=True) def get_absolute_url(self): return reverse('meetings:detail', kwargs={'slug': self.slug}) def __str__(self) -> str: return f'{self.start_date:%d.%m.%Y} - {self.location}: {self.title}'
2. 调整后台管理配置(admin.py)
你的Admin类已经继承了FrontendEditableAdminMixin,这个很好,它能让你在后台直接编辑占位符内容。现在只要补充配置,告诉后台哪些占位符可以编辑,以及这个模型对应的占位符slot:
from cms.admin.placeholderadmin import FrontendEditableAdminMixin from django.contrib import admin from .models import Meeting @admin.register(Meeting) class MeetingAdmin(FrontendEditableAdminMixin, admin.ModelAdmin): # 这里保留你原来的后台配置,比如: list_display = ('title', 'start_date', 'location') prepopulated_fields = {'slug': ('title',)} # 指定可前端编辑的占位符(对应模型里的缓存属性名称) frontend_editable_fields = ("body_placeholder",) # 注册这个模型可用的占位符slot placeholder_slots = ("body",)
3. 在模板里渲染占位符
最后,在会议详情的模板里,用CMS的render_placeholder标签来渲染这个body占位符的内容就行:
{% load cms_tags %} <!-- 你的其他模板内容 --> <div class="meeting-content"> {% render_placeholder meeting.body_placeholder %} </div>
4. 数据库迁移(必做)
因为你删掉了原来的body TextField,得生成并执行数据库迁移:
python manage.py makemigrations python manage.py migrate
要是原来的body字段里有现有数据,你还得写个数据迁移脚本把这些文本转移到新的占位符里。大概思路就是遍历所有Meeting实例,给每个实例的body占位符创建一个TextPlugin,把原来的文本内容塞进去,再保存关联就行。
5. 限制可用插件(可选)
如果你想指定"body"占位符只能用某些CMS插件(比如只允许文本、图片),可以在settings.py的CMS_PLACEHOLDER_CONF里配置:
CMS_PLACEHOLDER_CONF = { "body": { "plugins": ["TextPlugin", "ImagePlugin"], "name": "会议内容", "default_plugins": [ { "plugin_type": "TextPlugin", "values": {"body": "<p>请输入会议详情...</p>"}, } ] }, # 其他占位符slot的配置 }
备注:内容来源于stack exchange,提问作者Rockbot

