Как изменить текстовое поле модели django, чтобы оно стало полем-плейсхолдером django-cms
Я включил простое приложение в установку django-cms 4.1.1 и подключил его с помощью apphook, следуя учебникам.
model.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
, чтобы оно стало Placeholder-Field. В django-cms < 4 это делалось с помощью body = PlaceholderField('body')
, но, если я правильно понимаю, это устарело в версии 4.
admin.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()
, сделайте так:
models.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_structure.html
{% load cms_tags %}
{% placeholder "The Placeholder" %}
Чтобы отобразить 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)]