From dbc4917db9b852210b9e7d5f5eca3afe3a526643 Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Thu, 11 Jun 2026 16:27:59 +0330 Subject: [PATCH] admin panel multilanguals added --- apps/course/models/course.py | 33 ++++++++++++++++++++++++++++++-- apps/course/serializers/admin.py | 8 +++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/apps/course/models/course.py b/apps/course/models/course.py index c468f86..2a5def9 100644 --- a/apps/course/models/course.py +++ b/apps/course/models/course.py @@ -3,6 +3,7 @@ from decimal import Decimal import math from django.db import models from django.db.models import TextChoices +from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from apps.account.models import ProfessorUser @@ -77,7 +78,7 @@ def get_localized_field(lang, field_value): def course_file_upload_to(instance, filename): - return os.path.join(f"courses/{instance.slug}/videos/{filename}") + return os.path.join(f"courses/{get_course_storage_slug(instance)}/videos/{filename}") def attachment_file_upload_to(instance, filename): @@ -85,7 +86,35 @@ def attachment_file_upload_to(instance, filename): def course_attachment_file_upload_to(instance, filename): - return os.path.join(f"courses/{instance.course.slug}/attachments/{filename}") + return os.path.join( + f"courses/{get_course_storage_slug(instance.course)}/attachments/{filename}" + ) + + +def get_course_storage_slug(instance): + slug_source = instance.slug + + if isinstance(slug_source, list): + for lang in ("en", "fa", "ru"): + for item in slug_source: + if isinstance(item, dict) and item.get("language_code") == lang: + localized_slug = item.get("title") or item.get("value") or item.get("text") or item.get("name") + safe_slug = slugify(str(localized_slug or "")) + if safe_slug: + return safe_slug + + safe_slug = slugify(extract_text_from_json(slug_source)) + if safe_slug: + return safe_slug + + safe_title = slugify(extract_text_from_json(instance.title)) + if safe_title: + return safe_title + + if instance.pk: + return f"course-{instance.pk}" + + return "course-draft" diff --git a/apps/course/serializers/admin.py b/apps/course/serializers/admin.py index 27b545f..e00b867 100644 --- a/apps/course/serializers/admin.py +++ b/apps/course/serializers/admin.py @@ -63,6 +63,8 @@ class AdminLessonSerializer(serializers.ModelSerializer): return ret class AdminGlossarySerializer(serializers.ModelSerializer): + description_i18n = serializers.JSONField(source='description', read_only=True) + class Meta: model = Glossary fields = '__all__' @@ -74,6 +76,8 @@ class AdminGlossarySerializer(serializers.ModelSerializer): return ret class AdminAttachmentSerializer(serializers.ModelSerializer): + title_i18n = serializers.JSONField(source='title', read_only=True) + class Meta: model = Attachment fields = '__all__' @@ -386,6 +390,7 @@ class AdminCourseAttachmentSerializer(serializers.Serializer): 'course': instance.course_id, 'attachment': instance.attachment_id, 'title': localized_title, + 'title_i18n': raw_title, 'file': serialize_file(attachment_obj.file, self) if attachment_obj and attachment_obj.file else None, 'file_size': attachment_obj.file_size if attachment_obj else 0 } @@ -455,7 +460,8 @@ class AdminCourseGlossarySerializer(serializers.Serializer): 'course': instance.course_id, 'glossary': instance.glossary_id, 'title': glossary_obj.title if glossary_obj else "", - 'description': localized_description + 'description': localized_description, + 'description_i18n': raw_description, } def create(self, validated_data):