我已将一个简单的应用程序包含到 django-cms 4.1.1 安装中,并按照教程将其与 apphook 连接。
模型.py:
class Meeting(models.Model):
# some fields above...
body = models.TextField(_('body'),
default='',
blank=True
)
placeholders = PlaceholderRelationField()
@cached_property
def placeholder_test(self):
return get_placeholder_from_slot(self.placeholders, "body")
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}'
我想将
body
字段更改为占位符字段。在 django-cms < 4 this was done with body = PlaceholderField('body')
但如果我理解正确的话,这在版本 4 中已经过时了。
管理员.py
from cms.admin.placeholderadmin import FrontendEditableAdminMixin
from django.contrib import admin
from .models import Meeting
class MeetingAdmin(FrontendEditableAdminMixin, admin.ModelAdmin):
pass
admin.site.register(Meeting, MeetingAdmin)
meeting_detail.html
{% block content %}
{% render_placeholder meeting.placeholder_test %}
{% endblock content %}
但是前端没有出现任何占位符来填充插件。这怎么可能?
django-cms 4 中的行为发生了变化。不要声明像
my_field = PlaceholderField()
这样的字段,而是这样做:
模型.py
# imports +
from cms.models.fields import PlaceholderRelationField
from cms.utils.placeholder import get_placeholder_from_slot
from django.utils.functional import cached_property
class YourModel(models.Model):
# Your fields +
placeholders = PlaceholderRelationField()
@cached_property
def placeholder(self):
return get_placeholder_from_slot(self.placeholders, "The Placeholder")
def get_template(self):
return "your_app/yourmodel_structure.html"
# Methods ...
yourmodel_struct.html
{% load cms_tags %}
{% placeholder "The Placeholder" %}
在
your_app
的模板中渲染占位符,例如
yourmodel_detail.html
{% load cms_tags %}
{% render_placeholder yourmodel.placeholder %}
views.py
# Imports +
from django.shortcuts import get_object_or_404, render
from .models import YourModel
# Views... +
def render_your_model(request, obj):
return render(
request,
"your_app/yourmodel_detail.html",
{
"obj": obj,
},
)
def meeting_detail(request, id):
# Get the object, here by id
obj = get_object_or_404(Meeting, id=id)
# Announce the object to the toolbar
request.toolbar.set_object(obj)
# Same as preview rendering
return render_your_model(request, obj)
urls.py
from django.urls import path
from . import views
app_name = 'your_app'
urlpatterns = [
# Paths +
path('<id:id>/', views.yourmodel_detail, name='detail'),
]
admin.py
# Imports +
from cms.admin.placeholderadmin import FrontendEditableAdminMixin
from .models import YourModel
# FrontendEditableAdminMixin First!
class YourModelAdmin(FrontendEditableAdminMixin, admin.ModelAdmin):
pass
admin.site.register(YourModel, YourModelAdmin)
cms_config.py
from cms.app_base import CMSAppConfig
from . import models, views
class YourModelConfig(CMSAppConfig):
cms_enabled = True
cms_toolbar_enabled_models = [(models.YourModel, views.render_your_model)]