7 changed files with 280 additions and 16 deletions
-
8apps/quiz/admin/question.py
-
25apps/quiz/admin/quiz.py
-
137apps/quiz/migrations/0005_multilingual_quiz_fields.py
-
24apps/quiz/models/quiz.py
-
46apps/quiz/serializers/admin.py
-
35apps/quiz/serializers/quiz.py
-
21apps/quiz/views/admin.py
@ -0,0 +1,137 @@ |
|||||
|
# Generated by Codex on 2026-06-11 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
def _is_multilingual_list(value): |
||||
|
return isinstance(value, list) and all( |
||||
|
isinstance(item, dict) and item.get("language_code") |
||||
|
for item in value |
||||
|
) |
||||
|
|
||||
|
|
||||
|
def _normalize_multilingual(value): |
||||
|
if value in (None, "", []): |
||||
|
return [] |
||||
|
|
||||
|
if _is_multilingual_list(value): |
||||
|
normalized_items = [] |
||||
|
for item in value: |
||||
|
title = item.get("title") or item.get("text") or item.get("value") or item.get("name") |
||||
|
language_code = item.get("language_code") or "en" |
||||
|
if title: |
||||
|
normalized_items.append({"title": title, "language_code": language_code}) |
||||
|
return normalized_items |
||||
|
|
||||
|
if isinstance(value, dict): |
||||
|
language_map_keys = {"fa", "en", "ru", "ar", "tr"} |
||||
|
if any(key in value for key in language_map_keys): |
||||
|
return [ |
||||
|
{"title": title, "language_code": language_code} |
||||
|
for language_code, title in value.items() |
||||
|
if title |
||||
|
] |
||||
|
|
||||
|
title = value.get("title") or value.get("text") or value.get("value") or value.get("name") |
||||
|
language_code = value.get("language_code") or "en" |
||||
|
return [{"title": title, "language_code": language_code}] if title else [] |
||||
|
|
||||
|
if isinstance(value, list): |
||||
|
normalized_items = [] |
||||
|
for item in value: |
||||
|
if isinstance(item, dict): |
||||
|
title = item.get("title") or item.get("text") or item.get("value") or item.get("name") |
||||
|
language_code = item.get("language_code") or "en" |
||||
|
if title: |
||||
|
normalized_items.append({"title": title, "language_code": language_code}) |
||||
|
elif item not in (None, ""): |
||||
|
normalized_items.append({"title": str(item), "language_code": "en"}) |
||||
|
return normalized_items |
||||
|
|
||||
|
return [{"title": str(value), "language_code": "en"}] |
||||
|
|
||||
|
|
||||
|
def forwards(apps, schema_editor): |
||||
|
Quiz = apps.get_model("quiz", "Quiz") |
||||
|
Question = apps.get_model("quiz", "Question") |
||||
|
|
||||
|
for quiz in Quiz.objects.all().iterator(): |
||||
|
quiz.title_i18n = _normalize_multilingual(quiz.title) |
||||
|
quiz.description_i18n = _normalize_multilingual(quiz.description) |
||||
|
quiz.save(update_fields=["title_i18n", "description_i18n"]) |
||||
|
|
||||
|
for question in Question.objects.all().iterator(): |
||||
|
question.question_i18n = _normalize_multilingual(question.question) |
||||
|
question.option1_i18n = _normalize_multilingual(question.option1) |
||||
|
question.option2_i18n = _normalize_multilingual(question.option2) |
||||
|
question.option3_i18n = _normalize_multilingual(question.option3) |
||||
|
question.option4_i18n = _normalize_multilingual(question.option4) |
||||
|
question.save( |
||||
|
update_fields=[ |
||||
|
"question_i18n", |
||||
|
"option1_i18n", |
||||
|
"option2_i18n", |
||||
|
"option3_i18n", |
||||
|
"option4_i18n", |
||||
|
] |
||||
|
) |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
("quiz", "0004_alter_question_options"), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AddField( |
||||
|
model_name="quiz", |
||||
|
name="title_i18n", |
||||
|
field=models.JSONField(default=list, help_text="Quiz Title", verbose_name="Title"), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name="quiz", |
||||
|
name="description_i18n", |
||||
|
field=models.JSONField(blank=True, default=list, verbose_name="Description"), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name="question", |
||||
|
name="question_i18n", |
||||
|
field=models.JSONField(default=list, verbose_name="Question"), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name="question", |
||||
|
name="option1_i18n", |
||||
|
field=models.JSONField(default=list, verbose_name="Option 1"), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name="question", |
||||
|
name="option2_i18n", |
||||
|
field=models.JSONField(default=list, verbose_name="Option 2"), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name="question", |
||||
|
name="option3_i18n", |
||||
|
field=models.JSONField(default=list, verbose_name="Option 3"), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name="question", |
||||
|
name="option4_i18n", |
||||
|
field=models.JSONField(default=list, verbose_name="Option 4"), |
||||
|
), |
||||
|
migrations.RunPython(forwards, migrations.RunPython.noop), |
||||
|
migrations.RemoveField(model_name="quiz", name="title"), |
||||
|
migrations.RemoveField(model_name="quiz", name="description"), |
||||
|
migrations.RemoveField(model_name="question", name="question"), |
||||
|
migrations.RemoveField(model_name="question", name="option1"), |
||||
|
migrations.RemoveField(model_name="question", name="option2"), |
||||
|
migrations.RemoveField(model_name="question", name="option3"), |
||||
|
migrations.RemoveField(model_name="question", name="option4"), |
||||
|
migrations.RenameField(model_name="quiz", old_name="title_i18n", new_name="title"), |
||||
|
migrations.RenameField(model_name="quiz", old_name="description_i18n", new_name="description"), |
||||
|
migrations.RenameField(model_name="question", old_name="question_i18n", new_name="question"), |
||||
|
migrations.RenameField(model_name="question", old_name="option1_i18n", new_name="option1"), |
||||
|
migrations.RenameField(model_name="question", old_name="option2_i18n", new_name="option2"), |
||||
|
migrations.RenameField(model_name="question", old_name="option3_i18n", new_name="option3"), |
||||
|
migrations.RenameField(model_name="question", old_name="option4_i18n", new_name="option4"), |
||||
|
] |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue