Skip to content

Commit

Permalink
Restructure api
Browse files Browse the repository at this point in the history
  • Loading branch information
fsbraun committed May 24, 2024
1 parent 89bbe7a commit aa0edcb
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 104 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,5 @@ jobs:
run: pip install --upgrade ruff
- name: Run ruff
run: |
ruff djangocms_text
ruff djangocms_text_ckeditor
ruff djangocms_rest
ruff tests
7 changes: 0 additions & 7 deletions .github/workflows/publish-to-live-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ jobs:
pip install
build
--user
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Install dependencies
run: npm install
- name: Build client
run: webpack --mode production
- name: Build a binary wheel and a source tarball
run: >-
python -m
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
Sure, here's a basic `README.md` file for your Django CMS REST project:
# Django CMS REST

This is a demo project that provides RESTful APIs for Django CMS.
Expand Down
91 changes: 64 additions & 27 deletions djangocms_rest/serializers/pageserializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,72 @@


class RESTPage:
def __init__(self, request: Request, page: Page, language: str | None = None) -> None:
host = f"{request.scheme}://{request.get_host()}/"
def __init__(
self, request: Request, page: Page, language: str | None = None
) -> None:
host = f"{request.scheme}://{request.get_host()}"
page_content = page.get_content_obj(language, fallback=True)
self.title: str = page_content.title if page_content else None
self.page_title: str = page_content.page_title or self.title if page_content else None
self.menu_title: str = page_content.menu_title or self.title if page_content else None
self.meta_description: str = page_content.meta_description if page_content else None
self.redirect: str = page_content.redirect if page_content else None
self.absolute_url: str = page.get_absolute_url(language)
if page_content:
self.title: str = page_content.title
self.page_title: str = page_content.page_title or self.title
self.menu_title: str = page_content.menu_title or self.title
self.meta_description: str = page_content.meta_description
self.redirect: str = page_content.redirect
placeholders = page.get_placeholders(language)
declared_slots = [
placeholder.slot for placeholder in page.get_declared_placeholders()
]
content_type_id = ContentType.objects.get_for_model(
page_content.__class__
).pk
self.placeholders: dict[str, str] = (
{
placeholder.slot: host
+ reverse(
"placeholder-detail",
args=(
language,
content_type_id,
page_content.pk,
placeholder.slot,
),
)
for placeholder in placeholders
if placeholder.slot in declared_slots
}
if page_content
else {}
)
self.in_navigation: bool = page_content.in_navigation
self.soft_root: bool = page_content.soft_root
self.template: str = page_content.template
self.xframe_options: str = page_content.xframe_options
self.limit_visibility_in_menu: int = page_content.limit_visibility_in_menu
self.language: str = page_content.language
self.creation_date: datetime.datetime = page_content.creation_date
self.changed_date: datetime.datetime = page_content.changed_date
else:
self.title: str = ""
self.page_title: str = ""
self.menu_title: str = ""
self.meta_description: str = ""
self.redirect: str = ""
self.placeholders: dict[str, str] = {}

placeholders = page.get_placeholders(language)
declared_slots = [placeholder.slot for placeholder in page.get_declared_placeholders()]
content_type_id = ContentType.objects.get_for_model(page_content.__class__).pk
self.placeholders: dict[str, str] = {
placeholder.slot: host + reverse("placeholder-detail", args=(
language, content_type_id, page_content.pk, placeholder.slot
)) for placeholder in placeholders if placeholder.slot in declared_slots
} if page_content else {}
self.path:str = page.get_path(language)
self.in_navigation: bool = False
self.soft_root: bool = False
self.template: str = ""
self.xframe_options: str = ""
self.limit_visibility_in_menu: int = 0
self.language: str = page_content.language
self.creation_date: datetime.datetime = page_content.creation_date
self.changed_date: datetime.datetime = page_content.changed_date

self.is_home: bool = page.is_home
self.in_navigation: bool = page_content.in_navigation if page_content else None
self.soft_root: bool = page_content.soft_root if page_content else None
self.template: bool = page_content.template if page_content else None
self.xframe_options: bool = page_content.xframe_options if page_content else None
self.limit_visibility_in_menu: bool = page_content.limit_visibility_in_menu if page_content else None
self.absolute_url: str = page.get_absolute_url(language)
self.path: str = page.get_path(language)

self.language: str = page_content.language if page_content else None
self.is_home: bool = page.is_home
self.languages: list[str] = page.languages.split(",")
self.creation_date: datetime.datetime = page_content.creation_date if page_content else None
self.changed_date: datetime.datetime = page_content.changed_date if page_content else None
super().__init__()


Expand All @@ -63,4 +98,6 @@ class PageSerializer(serializers.Serializer):
language = serializers.CharField(max_length=10)
creation_date = serializers.DateTimeField()
changed_date = serializers.DateTimeField()
languages = serializers.ListSerializer(child=serializers.CharField(), allow_empty=True, required=False)
languages = serializers.ListSerializer(
child=serializers.CharField(), allow_empty=True, required=False
)
70 changes: 51 additions & 19 deletions djangocms_rest/serializers/placeholder.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import time

from cms.cache.placeholder import _get_placeholder_cache_key, _get_placeholder_cache_version_key
from cms.models import Placeholder, CMSPlugin
from cms.plugin_rendering import ContentRenderer, BaseRenderer
from cms.cache.placeholder import (
_get_placeholder_cache_key,
_get_placeholder_cache_version_key,
)
from cms.models import Placeholder
from cms.plugin_rendering import BaseRenderer
from cms.utils.conf import get_cms_setting
from cms.utils.plugins import get_plugins
from django.contrib.sites.shortcuts import get_current_site
Expand All @@ -25,11 +28,15 @@ def _get_placeholder_cache_version(placeholder, lang, site_id):
else:
version = int(time.time() * 1000000)
vary_on_list = []
_set_placeholder_cache_version(placeholder, lang, site_id, version, vary_on_list)
_set_placeholder_cache_version(
placeholder, lang, site_id, version, vary_on_list
)
return version, vary_on_list


def _set_placeholder_cache_version(placeholder, lang, site_id, version, vary_on_list=None, duration=None):
def _set_placeholder_cache_version(
placeholder, lang, site_id, version, vary_on_list=None, duration=None
):
"""
Sets the (placeholder x lang)'s version and vary-on header-names list.
"""
Expand All @@ -55,8 +62,8 @@ def set_placeholder_rest_cache(placeholder, lang, site_id, content, request):
key = _get_placeholder_cache_key(placeholder, lang, site_id, request) + ":rest"

duration = min(
get_cms_setting('CACHE_DURATIONS')['content'],
placeholder.get_cache_expiration(request, now())
get_cms_setting("CACHE_DURATIONS")["content"],
placeholder.get_cache_expiration(request, now()),
)
cache.set(key, content, duration)
# "touch" the cache-version, so that it stays as fresh as this content.
Expand All @@ -73,7 +80,10 @@ def get_placeholder_rest_cache(placeholder, lang, site_id, request):
"""
from django.core.cache import cache

key = _get_placeholder_cache_key(placeholder, lang, site_id, request, soft=True) + ":rest"
key = (
_get_placeholder_cache_key(placeholder, lang, site_id, request, soft=True)
+ ":rest"
)
content = cache.get(key)
return content

Expand All @@ -84,13 +94,14 @@ class PlaceholderRenderer(BaseRenderer):
"""

def placeholder_cache_is_enabled(self):
if not get_cms_setting('PLACEHOLDER_CACHE'):
if not get_cms_setting("PLACEHOLDER_CACHE"):
return False
if self.request.user.is_staff:
return False
return True

def render_placeholder(self, placeholder, context, language, use_cache=False):
context.update({"request": self.request})
if use_cache and placeholder.cache_placeholder:
use_cache = self.placeholder_cache_is_enabled()
else:
Expand All @@ -100,7 +111,7 @@ def render_placeholder(self, placeholder, context, language, use_cache=False):
cached_value = get_placeholder_rest_cache(
placeholder,
lang=language,
site_id=get_current_site().pk,
site_id=get_current_site(self.request).pk,
request=self.request,
)
else:
Expand All @@ -109,7 +120,7 @@ def render_placeholder(self, placeholder, context, language, use_cache=False):
if cached_value is not None:
# User has opted to use the cache
# and there is something in the cache
return cached_value['content']
return cached_value["content"]

plugin_content = self.render_plugins(
placeholder,
Expand All @@ -121,7 +132,7 @@ def render_placeholder(self, placeholder, context, language, use_cache=False):
set_placeholder_rest_cache(
placeholder,
lang=language,
site_id=get_current_site().pk,
site_id=get_current_site(self.request).pk,
content=plugin_content,
request=self.request,
)
Expand All @@ -132,7 +143,9 @@ def render_placeholder(self, placeholder, context, language, use_cache=False):

return plugin_content

def render_plugins(self, placeholder: Placeholder, language: str, context: dict) -> dict:
def render_plugins(
self, placeholder: Placeholder, language: str, context: dict
) -> list:
plugins = get_plugins(
self.request,
placeholder=placeholder,
Expand All @@ -144,40 +157,59 @@ def render_children(plugins):
for plugin in plugins:
plugin_content = self.render_plugin(plugin, context)
if getattr(plugin, "child_plugin_instances", None):
plugin_content["children"] = render_children(plugin.child_plugin_instances)
plugin_content["children"] = render_children(
plugin.child_plugin_instances
)
if plugin_content:
yield plugin_content

return render_children(plugins)
return list(render_children(plugins))

def render_plugin(self, instance, context):
instance, plugin = instance.get_plugin_instance()
if not instance:
return None
if hasattr(instance, "serializer") and issubclass(instance.serializer, serializers.Serializer):
if hasattr(instance, "serializer") and issubclass(
instance.serializer, serializers.Serializer
):
json = instance.serializer(instance, context=context).data
if hasattr(instance, "serialize"):
json = instance.serialize(context=context)

class PluginSerializer(serializers.ModelSerializer):
class Meta:
model = instance.__class__
fields = '__all__'
exclude = (
"id",
"placeholder",
"position",
"creation_date",
"changed_date",
"parent",
)

json = PluginSerializer(instance, context=context).data
return json


class PlaceholderSerializer(serializers.Serializer):
slot = serializers.CharField()
content = serializers.ListSerializer(child=serializers.JSONField(), allow_empty=True, required=False)
label = serializers.CharField()
language = serializers.CharField()
content = serializers.ListSerializer(
child=serializers.JSONField(), allow_empty=True, required=False
)

def __init__(self, request: Request, placeholder: Placeholder, language: str, *args, **kwargs):
def __init__(
self, request: Request, placeholder: Placeholder, language: str, *args, **kwargs
):
renderer = PlaceholderRenderer(request)
placeholder.content = renderer.render_placeholder(
placeholder,
context={},
language=language,
use_cache=True,
)
placeholder.label = placeholder.get_label()
placeholder.language = language
super().__init__(placeholder, *args, **kwargs)
9 changes: 0 additions & 9 deletions djangocms_rest/serializers/site.py

This file was deleted.

13 changes: 6 additions & 7 deletions djangocms_rest/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
from . import views

urlpatterns = [
path('', views.SiteList.as_view()),
path('<int:site_id>/languages/', views.LanguageList.as_view()),
path('<int:site_id>/<slug:language>/pages', views.PageList.as_view()),
path('<int:site_id>/<slug:language>/pages/', views.PageDetail.as_view()),
path('<int:site_id>/<slug:language>/pages/<path:path>/', views.PageDetail.as_view()),
path("", views.LanguageList.as_view()),
path("<slug:language>/pages", views.PageList.as_view(), name="pages-list"),
path("<slug:language>/pages/", views.PageDetail.as_view(), name="pages-root"),
path("<slug:language>/pages/<path:path>/", views.PageDetail.as_view()),
path(
'placeholders/<slug:language>/<int:content_type_id>/<int:object_id>/<str:slot>/',
"<slug:language>/placeholders/<int:content_type_id>/<int:object_id>/<str:slot>/",
views.PlaceholderDetail.as_view(),
name='placeholder-detail',
name="placeholder-detail",
),
]

Expand Down
Loading

0 comments on commit aa0edcb

Please sign in to comment.