Browse Source

features and timings schema fixed

master
Mohsen Taba 2 months ago
parent
commit
24d8006e69
  1. 11
      apps/course/serializers/admin.py
  2. 73
      apps/course/serializers/course.py

11
apps/course/serializers/admin.py

@ -1,4 +1,4 @@
from rest_framework import serializers
from rest_framework import serializers
from utils import FileFieldSerializer, get_thumbs
from apps.course.models import (
Course,
@ -185,12 +185,8 @@ class AdminCourseDetailSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
ret = super().to_representation(instance)
lang = get_request_lang(self)
ret['title'] = get_localized_field(lang, instance.title)
ret['slug'] = get_localized_field(lang, instance.slug)
ret['level'] = get_localized_field(lang, instance.level)
ret['status'] = get_localized_field(lang, instance.status)
ret['timing'] = get_localized_field(lang, instance.timing)
ret['features'] = get_localized_field(lang, instance.features)
# Keep raw JSON values here so the admin form can edit all language variants,
# matching the blog admin flow.
return ret
@ -519,3 +515,4 @@ class AdminLiveSessionDetailSerializer(serializers.ModelSerializer):
return ""
lang = get_request_lang(self)
return get_localized_field(lang, obj.course.title)

73
apps/course/serializers/course.py

@ -5,6 +5,8 @@ from apps.course.models import Course, CourseCategory, Attachment, Glossary, Les
from apps.course.models.course import get_localized_field
from apps.chat.models import RoomMessage
from apps.account.serializers import UserProfileSerializer
import ast
import json
@ -413,25 +415,62 @@ class CourseDetailSerializer(serializers.ModelSerializer):
def get_status(self, obj):
return get_localized_field(self._lang(), obj.status)
def _parse_builder_payload(self, value):
if value is None:
return None
if isinstance(value, str):
for parser in (json.loads, ast.literal_eval):
try:
parsed = parser(value)
return parsed
except Exception:
continue
return value
return value
def _extract_builder_list(self, value):
"""
Return the raw builder list for the current language.
Supports both:
- direct lists like [{'day': 'monday', 'timing': '12:22'}, ...]
- multilingual wrappers like [{'language_code': 'en', 'title': "[...]"}, ...]
"""
parsed = self._parse_builder_payload(value)
if parsed is None:
return []
if isinstance(parsed, list) and parsed:
if all(isinstance(item, dict) and 'language_code' in item for item in parsed):
current_lang = self._lang()
selected = next(
(
item for item in parsed
if isinstance(item, dict) and item.get('language_code') == current_lang
),
parsed[0],
)
parsed = self._parse_builder_payload(
selected.get('title')
or selected.get('text')
or selected.get('value')
or selected.get('name')
or []
)
if isinstance(parsed, list):
return parsed
if isinstance(parsed, dict):
if isinstance(parsed.get('list'), list):
return parsed['list']
if isinstance(parsed.get('items'), list):
return parsed['items']
return []
def get_timing(self, obj):
import json
val = get_localized_field(self._lang(), obj.timing)
if isinstance(val, str):
try:
return json.loads(val)
except Exception:
pass
return val
return self._extract_builder_list(obj.timing)
def get_features(self, obj):
import json
val = get_localized_field(self._lang(), obj.features)
if isinstance(val, str):
try:
return json.loads(val)
except Exception:
pass
return val
return self._extract_builder_list(obj.features)
@ -594,4 +633,4 @@ class CourseGlossarySerializer(serializers.ModelSerializer):
return getattr(request, 'LANGUAGE_CODE', None) or 'en'
def get_description(self, obj):
return get_localized_field(self._lang(), obj.glossary.description)
return get_localized_field(self._lang(), obj.glossary.description)
Loading…
Cancel
Save