Add method to the Django CMS Page Model

89 Views Asked by At

Problem/Gap

The Django CMS documentation clearly describes the process for extending the Page and Title Models. However, documentation on the possibility of adding a method such as the property method below is lacking, or I can't seem to find it.

Note: The example provided works perfectly when I include it directly under the Django CMS Page model. This is not the preferred way of course.

Question

Say I want to add the below method to the Page (cms.models.pagemodel.Page) or Title Model (assuming they are likely to follow the same process) outside the CMS app. How can this be achieved?

    @property
    def my_custom_page_property(self):
        try:
            logger.info(f'Working....')
            return {}

        except Exception as e:
            logger.error(f'Error: {e}')
            return {}

Attempt

In a seperate app I added the code below, and migrated. The image field is properly configured and works fine. The method however doesn't seem to return anything.

from cms.extensions import PageExtension
from cms.extensions.extension_pool import extension_pool

class MyCustomExtension(PageExtension):
    image = models.ForeignKey(Image,
                              on_delete=models.SET_DEFAULT,
                              default=None,
                              blank=True,
                              null=True)

    @property
    def my_custom_page_property(self):
        ..
1

There are 1 best solutions below

1
markwalker_ On

This is possible - I've set it up with a page extension I use for adding images to pages.

So taking the example;

class PageImage(PageExtension):
    """Add images to pages"""

    image = models.FileField(
        verbose_name=_("Image"),
        upload_to=upload_to("page_images"),
        validators=[validate_data_size, validate_file_name],
        blank=True,
        null=True,
    )

    gallery = models.ForeignKey(
        to="filer.Folder",
        verbose_name=_("Image gallery"),
        blank=True,
        null=True,
        related_name="page_gallery",
        on_delete=models.SET_NULL,
    )

    @property
    def test_prop(self):
        return "Hello world"

    class Meta:
        app_label = "cms_extras"
        verbose_name = _("CMS Page Image")
        verbose_name_plural = _("CMS Page Images")


extension_pool.register(PageImage)

Then in the template I've got;

        <div class="hero" style="background: url({% if request.current_page.pageimage.image %}{{ request.current_page.pageimage.image.url }}{% endif %}) center center no-repeat; background-size: cover;">
            <div class="hero__text-wrapper">
                <h1>{% if request.current_page.pageimage.image %}{{ request.current_page.pageimage.test_prop }}{% endif %}</h1>
            </div>
        </div>

This test_prop is being rendered to the page.