Browse Source

Optimize category admin API queries and include status description in hadis sync/list serializers

master
Mohsen Taba 3 weeks ago
parent
commit
d8670128ff
  1. 3
      apps/hadis/serializers/hadis.py
  2. 98
      apps/hadis/serializers/serializers_admin.py
  3. 6
      apps/hadis/views_admin.py

3
apps/hadis/serializers/hadis.py

@ -112,6 +112,7 @@ class HadisSyncSerializer(serializers.ModelSerializer):
status_block = {
'id': obj.hadis_status.id,
'title': get_localized_text(obj.hadis_status.title, request),
'description': get_localized_text(obj.hadis_status.description, request),
'color': obj.hadis_status.color,
'main_color_code': obj.hadis_status.main_color_code,
}
@ -295,10 +296,12 @@ class HadisListSerializer(serializers.ModelSerializer):
# Use your helper method
title = get_localized_text(obj.hadis_status.title, request)
description = get_localized_text(obj.hadis_status.description, request)
return {
'id': obj.hadis_status.id,
'title': title,
'description': description,
'color': obj.hadis_status.color,
'main_color_code': obj.hadis_status.main_color_code,
}

98
apps/hadis/serializers/serializers_admin.py

@ -1,6 +1,7 @@
from rest_framework import serializers
from django.core.files.uploadedfile import SimpleUploadedFile
from django.utils.translation import gettext_lazy as _
from django.db.models import Exists, OuterRef
from utils.image_compression import maybe_compress_uploaded_file
from utils import absolute_https_url
@ -800,6 +801,103 @@ class AdminHadisCategoryArchiveSerializer(serializers.ModelSerializer):
validated_data.pop("remove_xmind_file", False)
return super().create(validated_data)
class AdminHadisCategoryArchiveDetailSerializer(AdminHadisCategoryArchiveSerializer):
ancestors = serializers.SerializerMethodField()
children_type = serializers.SerializerMethodField()
child_categories = serializers.SerializerMethodField()
child_arguments = serializers.SerializerMethodField()
child_count = serializers.SerializerMethodField()
def get_ancestors(self, obj):
if not obj or not obj.pk:
return []
ancestors_qs = obj.get_ancestors(include_self=True).select_related("sect")
return [
{
"id": a.id,
"title": a.title,
"slug": a.slug,
"source_type": a.source_type,
"sect_type": a.sect.sect_type if a.sect else None,
"order": a.order,
"is_root": a.parent_id is None,
"level": getattr(a, a._mptt_meta.level_attr) if hasattr(a, "_mptt_meta") else 0,
}
for a in ancestors_qs
]
def get_children_type(self, obj):
if not obj or not obj.pk:
return "none"
has_children = bool(getattr(obj, "annotated_has_children", obj.children.exists()))
if has_children:
return "categories"
has_hadith = bool(getattr(obj, "annotated_has_hadith", obj.hadis_set.exists()))
if has_hadith:
return "arguments"
return "none"
def get_child_categories(self, obj):
if not obj or not obj.pk:
return []
child_hadis_subquery = Hadis.objects.filter(category=OuterRef("pk"))
child_children_subquery = HadisCategory.objects.filter(parent=OuterRef("pk"))
children = obj.children.all().annotate(
annotated_has_hadith=Exists(child_hadis_subquery),
annotated_has_children=Exists(child_children_subquery),
).order_by("order", "id")
return [
{
"id": c.id,
"title": c.title,
"slug": c.slug,
"order": c.order,
"source_type": c.source_type,
"has_children": bool(c.annotated_has_children),
"has_hadith": bool(c.annotated_has_hadith),
}
for c in children
]
def get_child_arguments(self, obj):
if not obj or not obj.pk:
return []
return [
{
"id": h.id,
"number": h.number,
"title": h.title,
"title_narrator": h.title_narrator,
"slug": h.slug,
"status": h.status,
"status_detail": {
"id": h.hadis_status.id,
"title": h.hadis_status.title,
"color": h.hadis_status.color,
"main_color_code": getattr(h.hadis_status, "main_color_code", None),
} if h.hadis_status else None,
}
for h in obj.hadis_set.all().select_related("hadis_status").order_by("number", "-id")[:100]
]
def get_child_count(self, obj):
if not obj or not obj.pk:
return 0
cat_count = obj.children.count()
if cat_count > 0:
return cat_count
return obj.hadis_set.count()
class Meta(AdminHadisCategoryArchiveSerializer.Meta):
fields = AdminHadisCategoryArchiveSerializer.Meta.fields + [
"ancestors",
"children_type",
"child_categories",
"child_arguments",
"child_count",
]
def update(self, instance, validated_data):
remove_xmind_file = validated_data.pop("remove_xmind_file", False)
if remove_xmind_file and instance.xmind_file:

6
apps/hadis/views_admin.py

@ -18,6 +18,7 @@ from .serializers.serializers_admin import (
AdminHadisCategorySerializer,
AdminHadisSectArchiveSerializer,
AdminHadisCategoryArchiveSerializer,
AdminHadisCategoryArchiveDetailSerializer,
AdminHadisCorrectionSerializer,
AdminHadisDetailSerializer,
AdminHadisInterpretationSerializer,
@ -97,6 +98,11 @@ class DovodiHadisCategoryViewSet(ModelViewSet):
pagination_class = None
parser_classes = (JSONParser, MultiPartParser, FormParser)
def get_serializer_class(self):
if self.action in ["retrieve"]:
return AdminHadisCategoryArchiveDetailSerializer
return AdminHadisCategoryArchiveSerializer
def get_queryset(self):
hadis_subquery = Hadis.objects.filter(category=OuterRef("pk"))
children_subquery = HadisCategory.objects.filter(parent=OuterRef("pk"))

Loading…
Cancel
Save