Skip to content

Commit

Permalink
Code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
fsbraun committed May 28, 2024
1 parent 607ad1c commit 4103d4d
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 52 deletions.
131 changes: 82 additions & 49 deletions djangocms_rest/serializers/pageserializer.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,48 @@

from cms.models import PageContent
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.urls import reverse
from rest_framework import serializers
from rest_framework.request import Request

from djangocms_rest.serializers.placeholder import PlaceholderRelationFieldSerializer

class RESTPage:
def __init__(
self, request: Request, page_content: PageContent
) -> None:
host = f"{request.scheme}://{request.get_host()}"
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_content.page.get_placeholders(page_content.language)
declared_slots = [
placeholder.slot for placeholder in page_content.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=(
page_content.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.absolute_url: str = page_content.page.get_absolute_url(page_content.language)
self.path: str = page_content.page.get_path(page_content.language)
class PageTreeSerializer(serializers.ListSerializer):
def __init__(self, tree, *args, **kwargs):
self.tree = tree
super().__init__(tree.get(None, []), *args, **kwargs)

self.is_home: bool = page_content.page.is_home
self.languages: list[str] = page_content.page.languages.split(",")
super().__init__()
def tree_to_representation(self, item):
repr = self.child.to_representation(item)
if item.page.node in self.tree:
repr["children"] = [
self.tree_to_representation(child) for child in self.tree[item.page.node]
]
return repr

def to_representation(self, data):
"""
List of object instances -> List of dicts of primitive datatypes.
"""
# Dealing with nested relationships, data can be a Manager,
# so, first get a queryset from the Manager if needed
iterable = data.all() if isinstance(data, models.manager.BaseManager) else data

class PageSerializer(serializers.Serializer):
return [
self.tree_to_representation(item) for item in iterable
]


class PageContentSerializer(serializers.Serializer):
title = serializers.CharField(max_length=255)
page_title = serializers.CharField(max_length=255)
menu_title = serializers.CharField(max_length=255)
meta_description = serializers.CharField()
redirect = serializers.CharField(max_length=2048)
absolute_url = serializers.URLField(max_length=200)

placeholders = serializers.DictField()
placeholders = serializers.JSONField()
path = serializers.CharField(max_length=200)

is_home = serializers.BooleanField()
Expand All @@ -78,3 +56,58 @@ class PageSerializer(serializers.Serializer):
languages = serializers.ListSerializer(
child=serializers.CharField(), allow_empty=True, required=False
)

def __init__(self, request: Request, *args, **kwargs) -> None:
self.request = request
super().__init__(*args, **kwargs)

@classmethod
def many_init(cls, request, instances, *args, **kwargs):
kwargs['child'] = cls(request)
if kwargs.pop("as_tree", True):
tree = {}
for instance in instances:
if instance.page.node.parent in tree:
tree[instance.page.node.parent].append(instance)
else:
tree[instance.page.node.parent] = [instance]
return PageTreeSerializer(tree, *args, **kwargs)
return serializers.ListSerializer(instances, *args, **kwargs)

def to_representation(self, page_content):
declared_slots = [
placeholder.slot
for placeholder in page_content.page.get_declared_placeholders()
]
print(f"{declared_slots=}")
placeholders = [
placeholder
for placeholder in page_content.page.get_placeholders(page_content.language)
if placeholder.slot in declared_slots
]

return {
"title": page_content.title,
"page_title": page_content.page_title or page_content.title,
"menu_title": page_content.menu_title or page_content.title,
"meta_description": page_content.meta_description,
"redirect": page_content.redirect,
"placeholders": PlaceholderRelationFieldSerializer(
self.request,
page_content,
placeholders,
page_content.language,
).data,
"in_navigation": page_content.in_navigation,
"soft_root": page_content.soft_root,
"template": page_content.template,
"xframe_options": page_content.xframe_options,
"limit_visibility_in_menu": page_content.limit_visibility_in_menu,
"language": page_content.language,
"absolute_url": page_content.page.get_absolute_url(
page_content.language
),
"path": page_content.page.get_path(page_content.language),
"is_home": page_content.page.is_home,
"languages": page_content.page.languages.split(","),
}
37 changes: 37 additions & 0 deletions djangocms_rest/serializers/placeholder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
from cms.plugin_rendering import BaseRenderer, ContentRenderer
from cms.utils.conf import get_cms_setting
from cms.utils.plugins import get_plugins
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.shortcuts import get_current_site
from django.db import models
from django.template.defaulttags import now
from django.urls import reverse
from rest_framework import serializers
from rest_framework.request import Request
from sekizai.context import SekizaiContext
Expand Down Expand Up @@ -238,3 +241,37 @@ def render_html(self, request, placeholder, language):
"html": content,
**{key: "".join(value) for key, value in sekizai_blocks.items() if value},
}


class PlaceholderRelationFieldSerializer(serializers.Serializer):
def __init__(self, request: Request, instance: models.Model, placeholders, language: str, *args, **kwargs) -> None:
self.placeholders = placeholders
self.language: str = language
super().__init__(instance,*args, **kwargs)
self.host: str = f"{request.scheme}://{request.get_host()}"

for placeholder in self.placeholders:
self.fields[placeholder.slot] = serializers.JSONField()

def to_representation(self, instance):
content_type_id = ContentType.objects.get_for_model(
instance.__class__
).pk

return (
{
placeholder.slot: self.host
+ reverse(
"placeholder-detail",
args=(
self.language,
content_type_id,
instance.pk,
placeholder.slot,
),
)
for placeholder in self.placeholders
}
if instance
else {}
)
6 changes: 3 additions & 3 deletions djangocms_rest/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from rest_framework.response import Response
from rest_framework.views import APIView as DRFAPIView

from djangocms_rest.serializers.pageserializer import PageSerializer, RESTPage
from djangocms_rest.serializers.pageserializer import PageContentSerializer
from djangocms_rest.serializers.placeholder import PlaceholderSerializer


Expand Down Expand Up @@ -46,11 +46,11 @@ def get(self, request, language, format=None):
if request.user.is_anonymous:
qs = qs.filter(login_required=False)
pages = (
RESTPage(request, page.get_content_obj(language, fallback=True))
page.get_content_obj(language, fallback=True)
for page in qs
if user_can_view_page(request.user, page) and page.get_content_obj(language, fallback=True)
)
serializer = PageSerializer(pages, many=True, read_only=True)
serializer = PageContentSerializer(request, pages, many=True, read_only=True)
return Response(serializer.data)


Expand Down

0 comments on commit 4103d4d

Please sign in to comment.