Как изменить текстовое поле модели 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)]
Вернуться на верх