import wagtail.api.v2.serializers as wagtail_serializers from rest_framework.fields import SerializerMethodField from vbv_lernwelt.course.models import CoursePage from vbv_lernwelt.course.serializers import CourseCategorySerializer, CourseSerializer from vbv_lernwelt.learnpath.utils import get_wagtail_type def get_it_serializer_class(model, field_names): return wagtail_serializers.get_serializer_class(model, field_names=field_names, meta_fields=[], base=ItBaseSerializer) class ItTypeField(wagtail_serializers.TypeField): def to_representation(self, obj): name = get_wagtail_type(obj) return name class ItBaseSerializer(wagtail_serializers.BaseSerializer): type = ItTypeField(read_only=True) children = SerializerMethodField() course = SerializerMethodField() course_category = CourseCategorySerializer(read_only=True) meta_fields = [] def __init__(self, *args, **kwargs): self.descendants = kwargs.pop('descendants', None) super().__init__(*args, **kwargs) def get_children(self, obj): if not self.descendants: self.descendants = [p for p in obj.get_descendants().specific()] children = _get_children(self.descendants, obj) return [c.specific.get_serializer_class()(c.specific, descendants=self.descendants).data for c in children] def get_course(self, obj): if hasattr(obj, 'course'): return CourseSerializer(obj.course).data else: course_parent_page = obj.get_ancestors().exact_type(CoursePage).last() if course_parent_page: return CourseSerializer(course_parent_page.specific.course).data return '' def _get_descendants(pages, obj): return [c for c in pages if c.path.startswith(obj.path) and c.depth >= obj.depth] def _get_children(pages, obj): return [c for c in pages if c.path.startswith(obj.path) and obj.depth + 1 == c.depth]