Preview and versioning

The API serves published content to the public, but editors need to see work in progress. This page explains the published/draft split, how a preview request switches between them, and how access is controlled.

Published vs. draft content

When djangocms-versioning is in use, each PageContent can exist in more than one state — typically a published version and a newer draft. django CMS exposes these through two managers on the content model:

  • the default (content) manager, which yields published content;

  • an admin_manager, which can yield draft content for editors.

djangocms-rest chooses between them per request. Normal requests read published content; preview requests read draft content via the admin manager. This is also why placeholders are decoupled from the page object (see The content model): the same placeholder slot can resolve to different content depending on the version being viewed.

What a preview request does

A request is treated as preview when it carries a preview query parameter whose value is anything other than 0 or false (so ?preview, ?preview=true and ?preview=1 all enable it). When preview is active:

  1. Admin access is required. An IsAdminUser check is applied first, so anonymous and non-staff users are rejected before any content is read.

  2. Per-object permissions still apply. Even for staff, django CMS’s user_can_view_page() decides whether this user may see this page. A failing check returns 404 — the API does not reveal the existence of content you cannot see.

  3. Draft content is read through the admin manager instead of the published manager.

Why session authentication

Preview authorisation reuses the editor’s existing django CMS admin session rather than introducing API tokens. The user who is allowed to edit in the admin is exactly the user allowed to preview through the API, governed by the same permission rules — there is no second, parallel access model to keep in sync. The practical consequence is that a cross-origin frontend must send the session cookie, which is what the Access draft (preview) content guide configures.

Placeholders already in draft

When you fetch a placeholder that belongs to a draft object directly, the draft content is already what is being queried, so adding ?preview makes no further difference at that step. Preview matters at the point where the API decides which version of a page’s content to resolve.

See also