Installation¶
Requirements¶
djangocms-rest requires:
Python 3.9 or higher
Django 4.2 or higher
django CMS 4.0 or higher, including latest 5.0+ versions
Django REST Framework 3.14 or higher
Installation¶
Note
A running Django CMS project is required. Follow the Installing Django CMS by hand guide to get started.
Using Poetry¶
We recommend using Poetry to manage your dependencies. It is used by default in this documentation.
pip can be used as equivalent.
poetry add djangocms-rest
Using pip¶
pip install djangocms-rest
Latest from source¶
For the latest features, you can install a version from the GitHub repository at your own risk:
poetry add git+https://github.com/django-cms/djangocms-rest.git
# install a specific branch
poetry add git+https://github.com/django-cms/djangocms-rest.git@feat/extended-search
Basic Configuration¶
Add
djangocms_restto yourINSTALLED_APPS:
INSTALLED_APPS = [
# ... other Django apps
...,
# django CMS
'cms',
# djangocms-rest
'djangocms_rest',
...,
]
Include the djangocms-rest URLs in your project’s main URL configuration:
# demo_cms/urls.py
from django.urls import path, include
urlpatterns = [
# ... other URL patterns
path('api/', include('djangocms_rest.urls')), #api can be changed to your liking
]
2.1 Add optional API prefix
Alternatively, you can put the API under a specific path, like api/cms/.
This is handy if you want to have a separate API for different parts of your app.
from django.urls import path, include
urlpatterns = [
# ... other URL patterns
path('api/', include('my_django_rest_app.urls')),
path('api/cms/', include('djangocms_rest.urls')),
]
Note
When you autocreate clients and types from OpenAPI specification with tools like heyapi.dev, this will also affect the naming of those components and types, e.g.
RetrieveLanguages will become CmsRetrieveLanguages in the client sdk.
CORS Support¶
If you want to serve the API from a different domain, you can use the CorsMiddleware to enable CORS.
This is optional, but likely needed for security reasons with decoupled frontend apps.
Docs¶
Configuration¶
poetry add django-cors-headers
# settings.py
INSTALLED_APPS = [
...,
"corsheaders",
...,
]
# add the allowed origins (your frontend apps) to the CORS settings
CORS_ALLOWED_ORIGINS = [
...,
"https://example.com", # set your own domain here, likely via env variable in production
"http://localhost:300", # common js frontend app port
"http://localhost:5173", # vue.js from our examples
...,
]
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
]
Languages Support¶
djangocms-rest supports languages out of the box.
Djnago CMS needs to be configured to use languages.
A single language must always be set in order to use the API.
Docs¶
Configuration¶
This is a simple configuration to get you started. Follow the Django CMS documentation to configure languages in-depth.
# settings.py
# Language settings
LANGUAGE_CODE = "en"
USE_I18N = True
LANGUAGES = (
("de", _("German")),
("en", _("English")),
)
CMS_LANGUAGES = {
1: [
{
"code": "en",
"name": "English",
"public": True,
},
{
"code": "de",
"name": _("Deutsch"),
"public": False,
"hide_untranslated": True,
},
],
"default": {
"fallbacks": ["en"],
"redirect_on_fallback": True,
"public": True,
"hide_untranslated": False,
},
}
MIDDLEWARE = [
...,
"cms.middleware.language.LanguageCookieMiddleware",
...,
]
# urls.py
# example configuration
urlpatterns += i18n_patterns(
path('admin/', include(admin.site.urls)),
path('', include('cms.urls')),
prefix_default_language=False,
)
Multi-Site Support¶
djangocms-rest supports 2 ways to handle multi-site support:
Multi-Instance Setup: Usually multiple instances of the CMS running on different domains. This is also valid option for headless mode. See the official Django CMS - Multi-Site installation documentation for more information.
Single Instance Setup: Run Django CMS in headless mode and serve multiple sites from a single instance. Using the
SiteContextMiddlewarefromdjangocms-restto set the site context on the request.
Option 1:
foo.example.com/api/pages/ < REQUEST > Content foo site
bar.example.com/api/pages/ < REQUEST > Content bar site
Option 2:
cms.example.com/api/pages/ < REQUEST HEADERS X-Site-ID: 1 > Content foo site
cms.example.com/api/pages/ < REQUEST HEADERS X-Site-ID: 2 > Content bar site
If you want to serve multiple sites from a single instance, you can use the SiteContextMiddleware to set the site context on the request.
This requires Django Sites framework to be installed and configured.
You can pass the site ID in the request headers with the X-Site-ID property set to the site ID.
The Middleware will then set the site context on the request.
Docs¶
For Option 2, you do not need to configure the webserver to manage multiples sites as the frontend apps are decoupled and run on a different domain.
Note
You need to have CORS configured correctly to allow the frontend app to access the API. See CORS Support.
Configuration¶
INSTALLED_APPS = [
...
'django.contrib.sites',
...
]
# default site id, you likely wnat to change this using env variable in production
SITE_ID = 1
CORS_ALLOW_ALL_ORIGINS=True # development seting, disable in production
CORS_ALLOWED_ORIGINS = [
"https://frontend.com", # your production frontend domain
"http://localhost:3000", # common js frontend app port
"http://localhost:5173", # vue.js from our examples
]
# we need to add the X-Site-ID header to the allowed headers
# Only required for single instance setup
CORS_ALLOW_HEADERS = (
*default_headers,
"X-Site-ID",
)
Manage Sites in Django Admin
Go to Django Admin → Sites
Add/edit sites with domain and name
Example:
// Manually configured via Django Admin
// you can seed the ID in the browser url while editing the site object
[
{
"domain": "foo.example.com",
"name": "Foo Site"
},
{
"domain": "bar.example.com",
"name": "Bar Site"
}
]
MIDDLEWARE = [
# Required for cross-origin requests (frontend on different domain)
"corsheaders.middleware.CorsMiddleware",
#before other middleware that depends on the site context
"djangocms_rest.middleware.SiteContextMiddleware",
# other django and django CMS middleware (depends on your setup)
...
]
Testing¶
Create a test home page for each site in the Django admin.
Publish the pages.
Test the API endpoints with the
X-Site-IDheader set to the site ID.
# pages endpoint without path will return the home page for the site
curl -H "X-Site-ID: 2" http://localhost:8080/api/cms/pages/
Note
The X-Site-ID header is required to query a single CMS instance. If not set, the middleware will use the current site defined in the settings.
Implementation Guide¶
If the basic configuration is working you can embed it into your frontend app.
Authentication¶
djangocms-rest currently uses Session Authentication as the only authentication method.
This means that users must be logged into the Django CMS admin using the standard admin login page to access protected API endpoints.
In order to access the API from the frontend app, you need to configure Django CORS and
CSRF.
Only authenticated users can access the API using the
previewquery parameter.
Docs¶
Note
You need to have CORS configured correctly to allow the frontend app to access the API. See CORS Support.
Configuration¶
# Additional CORS configuration for session authentication
CORS_ALLOW_CREDENTIALS = True
# add your frontend domain(s) here
CSRF_TRUSTED_ORIGINS = [
"https://frontend.com",
"http://localhost:3000",
"http://localhost:5173",
]
# allow session and csrf cookies to be sent to frontend
# required for session authentication to work
SESSION_COOKIE_SAMESITE = "None"
CSRF_COOKIE_SAMESITE = "None"
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
Testing¶
Login to Django admin at http://localhost:8080/admin/
Change the home page name, but do not publish it.
Visit and api endpoint with the
previewquery parameter.
# Adjust language if necessary
http://localhost:8080/api/en/pages/?preview=true
OpenAPI Documentation¶
For interactive API documentation and client SDK generation, follow the OpenAPI Documentation tutorial.
OpenAPI Documentation Benefits:
Interactive API documentation with Swagger UI
OpenAPI schema generation for client SDKs
Type-safe frontend development