Skip to content

feat: Add djangocms-rest support - #378

Merged
fsbraun merged 19 commits into
masterfrom
feat/rest-support
Aug 28, 2026
Merged

feat: Add djangocms-rest support#378
fsbraun merged 19 commits into
masterfrom
feat/rest-support

Conversation

@fsbraun

@fsbraun fsbraun commented Jun 28, 2026

Copy link
Copy Markdown
Member

Summary by Sourcery

Integrate optional djangocms-rest support to expose alias content via the headless API and ensure Alias plugins serialize correctly through REST endpoints.

New Features:

  • Expose alias placeholder content through a dedicated djangocms-rest alias-detail endpoint when djangocms-rest is installed.
  • Provide an inline REST serializer for Alias plugins so their referenced alias content is expanded directly in API responses.
  • Add a model-level hook returning the REST API endpoint URL for an alias for use by djangocms-rest serializers.

Enhancements:

  • Wire djangocms_alias cms and plugin configs to register djangocms-rest endpoints and serializers only when the dependency is present.
  • Extend test settings and URL configuration to conditionally mount djangocms-rest, including media and REST framework configuration needed for integration tests.

Tests:

  • Add end-to-end tests covering alias REST endpoint behavior, inline alias content serialization, foreign key URL resolution, and recursion guards for circular or nested aliases.

Related resources

  • #...
  • #...

Checklist

Summary by Sourcery

Integrate optional djangocms-rest support to expose alias content and serialize nested Alias plugins through the headless API.

New Features:

  • Add optional djangocms-rest API endpoints for listing aliases and retrieving localized alias placeholder content.
  • Expand Alias plugins inline in REST responses and expose alias references through API endpoint URLs.
  • Support published and permission-controlled preview access, site-aware static aliases, and recursion-safe nested alias serialization.

Enhancements:

  • Integrate REST support lazily so the package remains usable when djangocms-rest is not installed.

Build:

  • Refresh pinned test requirements and streamline per-Python dependency compilation through tox.

Documentation:

  • Document the new REST integration and usage.

Tests:

  • Add end-to-end coverage for alias endpoints, permissions, static alias resolution, foreign-key links, inline serialization, and circular alias protection.

@sourcery-ai

sourcery-ai Bot commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds optional integration with djangocms-rest, exposing alias placeholders via a headless API endpoint, wiring the Alias plugin to an inline serializer, and providing end-to-end REST tests guarded by conditional imports so behavior is unchanged when djangocms-rest is absent.

Sequence diagram for djangocms-rest alias placeholder API endpoint

sequenceDiagram
    actor Client
    participant Router as DjangoRouter
    participant View as AliasContentView
    participant AliasModel as Alias
    participant PlaceholderSerializer
    participant DRFResponse as Response

    Client->>Router: GET /<language>/aliases/<pk>/
    Router->>View: dispatch get(language, pk)
    View->>AliasModel: objects.filter(pk=pk).first()
    AliasModel-->>View: alias or None
    alt alias is None
        View->>View: raise NotFound
    else alias exists
        View->>AliasModel: get_placeholder(language, show_draft_content)
        AliasModel-->>View: placeholder or None
        alt placeholder is None
            View->>View: raise NotFound
        else placeholder exists
            View->>PlaceholderSerializer: __init__(instance=placeholder, request=request, language=language)
            View->>PlaceholderSerializer: data
            PlaceholderSerializer-->>View: serialized_placeholder
            View->>DRFResponse: __init__(serialized_placeholder)
            DRFResponse-->>Client: 200 OK
        end
    end
Loading

File-Level Changes

Change Details Files
Conditionally enable djangocms-rest and related apps/settings in the test project.
  • Detect djangocms_rest presence in tests.settings and compute HAS_REST/REST_INSTALLED_APPS accordingly
  • Extend INSTALLED_APPS with REST_INSTALLED_APPS so filer, easy_thumbnails, drf_spectacular, and djangocms_rest are loaded when available
  • Add MEDIA_URL and REST-related settings (THUMBNAIL_PROCESSORS, REST_FRAMEWORK, SPECTACULAR_SETTINGS) guarded by HAS_REST
  • Mount djangocms_rest URL patterns under /api/ in tests.urls when the package is installed
tests/settings.py
tests/urls.py
Expose alias content over a REST endpoint and integrate with djangocms-rest configuration hooks.
  • Add Alias.get_api_endpoint method to resolve per-language alias-detail URLs, returning None if the route is unavailable
  • Introduce djangocms_alias.rest module defining AliasContentView, AliasInlineSerializer, and djangocms-rest urlpatterns for alias-detail
  • Wire cms_config to import rest integration conditionally and register cms_rest_endpoints/cms_rest_enabled when present
djangocms_alias/models.py
djangocms_alias/cms_config.py
djangocms_alias/rest.py
Integrate Alias CMS plugin with djangocms-rest’s plugin serialization pipeline.
  • Conditionally import AliasInlineSerializer from the new rest module in cms_plugins
  • Assign AliasInlineSerializer as the Alias plugin’s serializer_class so alias content is expanded inline in REST responses while falling back when djangocms-rest is absent
djangocms_alias/cms_plugins.py
Add end-to-end tests covering alias REST integration, serialization, and recursion guards.
  • Introduce tests/test_rest.py with an AliasRESTIntegrationTestCase that exercises the alias-detail endpoint, 404 behavior, Alias.get_api_endpoint hook, serialize_fk integration, inline serializer wiring, page placeholder expansion, circular alias handling, and recursion-guard behavior
  • Use skipUnless(HAS_REST) gating to ensure tests only run when djangocms_rest is installed
tests/test_rest.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Comment thread tests/settings.py Fixed
Comment thread tests/test_rest.py Fixed
Comment thread tests/urls.py Fixed
Comment thread tests/urls.py Fixed
Co-authored-by: Marc Widmer <marc@pbi.io>
@fsbraun
fsbraun force-pushed the feat/rest-support branch from 1ef1d1e to d2685a0 Compare June 28, 2026 13:15
@metaforx

Copy link
Copy Markdown
Contributor

@fsbraun : I implemented the PR in my test setup. The plugin serialization works as expected. What i do not get is how we serialize a static alias, for example footer. I add one to my base template and either would expect serialization directly in pages or via endpoint and identifier "footer". Currently i can serialize it via id:

http://localhost:8080/api/en/aliases/2/

I would i expect to use the natural language identifiert "footer" similar to use in template:
{% static_alias 'footer' %}
http://localhost:8080/api/en/aliases/footer/

What is your take on this issue? Do i miss something?

Comment thread tests/test_rest.py
Comment thread tests/test_rest.py Fixed

@metaforx metaforx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fsbraun 👍

Comment thread djangocms_alias/models.py
# Conflicts:
#	djangocms_alias/models.py
#	tests/requirements/py312-dj52-cms51-default.txt
#	tests/requirements/py312-dj52-cms51-versioning.txt
#	tests/requirements/py313-dj52-cms50-default.txt
#	tests/requirements/py313-dj52-cms50-versioning.txt
#	tests/requirements/py313-dj60-cms50-default.txt
#	tests/requirements/py313-dj60-cms50-versioning.txt
#	tests/requirements/py314-dj52-cms50-default.txt
#	tests/requirements/py314-dj52-cms50-versioning.txt
#	tests/requirements/py314-dj60-cms50-default.txt
#	tests/requirements/py314-dj60-cms50-versioning.txt
#	tests/requirements/py314-dj61-cms50-default.txt
#	tests/requirements/py314-dj61-cms50-versioning.txt
@fsbraun
fsbraun marked this pull request as ready for review August 27, 2026 20:34

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @fsbraun, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 6 days and 11 hours by commenting @sourcery-ai review. Upgrade to get a review now.

fsbraun and others added 5 commits August 27, 2026 23:30
`HAS_REST` was hard-coded to `False`, so all 25 tests in the REST
integration suite skipped unconditionally. The comment next to it
deferred activation until djangocms-rest supported the cms_config hook;
that landed on djangocms-rest main in "feat: Allow django cms apps to
register for rest support" (#115), which is what
`tests/requirements/requirements.in` already tracks.

Probe for the package instead, mirroring `tests/settings.py`, which only
adds `djangocms_rest` and its dependencies to `INSTALLED_APPS` when it is
importable. Environments without it keep skipping.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwNaBKq7MNLhibbjjiAYHM
The djangocms-rest integration shipped without any mention in the README:
the two alias endpoints, addressing static aliases by their static code,
the ?preview=true draft access and its permission, and the inline
expansion of Alias plugins in page responses were all undocumented.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwNaBKq7MNLhibbjjiAYHM
@fsbraun
fsbraun merged commit 7aa25af into master Aug 28, 2026
14 checks passed
@fsbraun
fsbraun deleted the feat/rest-support branch August 28, 2026 19:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants