Browse Source

interpretations and corrections detail modal api added

master
Mohsen Taba 2 weeks ago
parent
commit
7f053d86f9
  1. 232
      apps/hadis/serializers/serializers_admin.py
  2. 4
      apps/hadis/views_admin.py

232
apps/hadis/serializers/serializers_admin.py

@ -5,7 +5,8 @@ from utils.image_compression import maybe_compress_uploaded_file
from ..models import ( from ..models import (
Hadis, HadisCategory, HadisStatus, HadisTag, HadisCorrection, HadisInterpretation, HadisCollection, HadisSect, HadisInCollection, HadisTransmitter, Hadis, HadisCategory, HadisStatus, HadisTag, HadisCorrection, HadisInterpretation, HadisCollection, HadisSect, HadisInCollection, HadisTransmitter,
BookReference, BookReferenceImage, BookReferenceDocument, BookAuthor, BookAttribute, BookSubjectArea, BookType, BookEdition, BookVolume, BookReference, BookReferenceImage, BookReferenceDocument, BookAuthor, BookAttribute, BookSubjectArea, BookType, BookEdition, BookVolume,
Transmitters, TransmitterReliability, NarratorLayer, OpinionStatus, TransmitterOpinion, TransmitterOriginalText
Transmitters, TransmitterReliability, NarratorLayer, OpinionStatus, TransmitterOpinion, TransmitterOriginalText,
CorrectionReference, CorrectionReferenceImage, InterpretationReference, InterpretationReferenceImage
) )
from .category import LocalizedField from .category import LocalizedField
@ -244,10 +245,62 @@ class AdminHadisCategoryBriefSerializer(serializers.ModelSerializer):
fields = ["id", "title"] fields = ["id", "title"]
def save_relation_reference_data(instance, validated_data, request=None, is_correction=True):
book_reference = validated_data.pop("book_reference_id", None)
address = validated_data.pop("address", None)
delete_image_ids = validated_data.pop("delete_image_ids", [])
new_images = request.FILES.getlist("uploaded_images") if request else []
ref = instance.references.first()
if not ref:
if book_reference or address or new_images:
if is_correction:
ref = CorrectionReference.objects.create(correction=instance)
else:
ref = InterpretationReference.objects.create(interpretation=instance)
else:
return
if book_reference is not None:
ref.book_reference = book_reference
if address is not None:
ref.address = address
ref.save()
if delete_image_ids:
ref.images.filter(id__in=delete_image_ids).delete()
for img in new_images:
if is_correction:
CorrectionReferenceImage.objects.create(reference=ref, image=img)
else:
InterpretationReferenceImage.objects.create(reference=ref, image=img)
class AdminHadisCorrectionSerializer(serializers.ModelSerializer): class AdminHadisCorrectionSerializer(serializers.ModelSerializer):
hadis_detail = AdminHadisBriefSerializer(source="hadis", read_only=True) hadis_detail = AdminHadisBriefSerializer(source="hadis", read_only=True)
bookmark_count = serializers.IntegerField(source="annotated_bookmark_count", read_only=True) bookmark_count = serializers.IntegerField(source="annotated_bookmark_count", read_only=True)
# Writable relation fields
book_reference_id = serializers.PrimaryKeyRelatedField(
queryset=BookReference.objects.all(),
required=False,
write_only=True,
allow_null=True
)
address = serializers.CharField(
required=False,
write_only=True,
allow_null=True,
allow_blank=True
)
delete_image_ids = serializers.ListField(
child=serializers.IntegerField(),
required=False,
write_only=True
)
class Meta: class Meta:
model = HadisCorrection model = HadisCorrection
fields = [ fields = [
@ -260,15 +313,113 @@ class AdminHadisCorrectionSerializer(serializers.ModelSerializer):
"translation", "translation",
"priority", "priority",
"bookmark_count", "bookmark_count",
"links",
"book_reference_id",
"address",
"delete_image_ids",
"created_at", "created_at",
"updated_at", "updated_at",
] ]
read_only_fields = ["id", "slug", "bookmark_count", "created_at", "updated_at"] read_only_fields = ["id", "slug", "bookmark_count", "created_at", "updated_at"]
def to_internal_value(self, data):
import json
data = data.copy() if hasattr(data, "copy") else dict(data)
for json_field in ["title", "translation", "links"]:
val = data.get(json_field)
if isinstance(val, str):
try:
data[json_field] = json.loads(val)
except ValueError:
pass
delete_ids = data.get("delete_image_ids")
if delete_ids:
if isinstance(delete_ids, str):
try:
data["delete_image_ids"] = json.loads(delete_ids)
except ValueError:
data["delete_image_ids"] = [int(x) for x in delete_ids.split(",") if x.strip().isdigit()]
elif isinstance(delete_ids, list):
parsed = []
for x in delete_ids:
if isinstance(x, str) and x.strip().isdigit():
parsed.append(int(x))
elif isinstance(x, int):
parsed.append(x)
data["delete_image_ids"] = parsed
return super().to_internal_value(data)
def to_representation(self, instance):
ret = super().to_representation(instance)
ref = instance.references.first()
ret["book_reference"] = ref.book_reference_id if ref else None
ret["address"] = ref.address if ref else ""
request = self.context.get("request")
ret["images"] = [
{
"id": img.id,
"image": request.build_absolute_uri(img.image.url) if request and img.image else img.image.url
}
for img in (ref.images.all() if ref else [])
]
return ret
def create(self, validated_data):
request = self.context.get("request")
book_reference_id = validated_data.pop("book_reference_id", None)
address = validated_data.pop("address", None)
delete_image_ids = validated_data.pop("delete_image_ids", [])
instance = super().create(validated_data)
ref_data = {
"book_reference_id": book_reference_id,
"address": address,
"delete_image_ids": delete_image_ids,
}
save_relation_reference_data(instance, ref_data, request=request, is_correction=True)
return instance
def update(self, instance, validated_data):
request = self.context.get("request")
book_reference_id = validated_data.pop("book_reference_id", None)
address = validated_data.pop("address", None)
delete_image_ids = validated_data.pop("delete_image_ids", [])
instance = super().update(instance, validated_data)
ref_data = {
"book_reference_id": book_reference_id,
"address": address,
"delete_image_ids": delete_image_ids,
}
save_relation_reference_data(instance, ref_data, request=request, is_correction=True)
return instance
class AdminHadisInterpretationSerializer(serializers.ModelSerializer): class AdminHadisInterpretationSerializer(serializers.ModelSerializer):
category_detail = AdminHadisCategoryBriefSerializer(source="category", read_only=True) category_detail = AdminHadisCategoryBriefSerializer(source="category", read_only=True)
# Writable relation fields
book_reference_id = serializers.PrimaryKeyRelatedField(
queryset=BookReference.objects.all(),
required=False,
write_only=True,
allow_null=True
)
address = serializers.CharField(
required=False,
write_only=True,
allow_null=True,
allow_blank=True
)
delete_image_ids = serializers.ListField(
child=serializers.IntegerField(),
required=False,
write_only=True
)
class Meta: class Meta:
model = HadisInterpretation model = HadisInterpretation
fields = [ fields = [
@ -279,11 +430,90 @@ class AdminHadisInterpretationSerializer(serializers.ModelSerializer):
"text", "text",
"translation", "translation",
"priority", "priority",
"links",
"book_reference_id",
"address",
"delete_image_ids",
"created_at", "created_at",
"updated_at", "updated_at",
] ]
read_only_fields = ["id", "created_at", "updated_at"] read_only_fields = ["id", "created_at", "updated_at"]
def to_internal_value(self, data):
import json
data = data.copy() if hasattr(data, "copy") else dict(data)
for json_field in ["title", "translation", "links"]:
val = data.get(json_field)
if isinstance(val, str):
try:
data[json_field] = json.loads(val)
except ValueError:
pass
delete_ids = data.get("delete_image_ids")
if delete_ids:
if isinstance(delete_ids, str):
try:
data["delete_image_ids"] = json.loads(delete_ids)
except ValueError:
data["delete_image_ids"] = [int(x) for x in delete_ids.split(",") if x.strip().isdigit()]
elif isinstance(delete_ids, list):
parsed = []
for x in delete_ids:
if isinstance(x, str) and x.strip().isdigit():
parsed.append(int(x))
elif isinstance(x, int):
parsed.append(x)
data["delete_image_ids"] = parsed
return super().to_internal_value(data)
def to_representation(self, instance):
ret = super().to_representation(instance)
ref = instance.references.first()
ret["book_reference"] = ref.book_reference_id if ref else None
ret["address"] = ref.address if ref else ""
request = self.context.get("request")
ret["images"] = [
{
"id": img.id,
"image": request.build_absolute_uri(img.image.url) if request and img.image else img.image.url
}
for img in (ref.images.all() if ref else [])
]
return ret
def create(self, validated_data):
request = self.context.get("request")
book_reference_id = validated_data.pop("book_reference_id", None)
address = validated_data.pop("address", None)
delete_image_ids = validated_data.pop("delete_image_ids", [])
instance = super().create(validated_data)
ref_data = {
"book_reference_id": book_reference_id,
"address": address,
"delete_image_ids": delete_image_ids,
}
save_relation_reference_data(instance, ref_data, request=request, is_correction=False)
return instance
def update(self, instance, validated_data):
request = self.context.get("request")
book_reference_id = validated_data.pop("book_reference_id", None)
address = validated_data.pop("address", None)
delete_image_ids = validated_data.pop("delete_image_ids", [])
instance = super().update(instance, validated_data)
ref_data = {
"book_reference_id": book_reference_id,
"address": address,
"delete_image_ids": delete_image_ids,
}
save_relation_reference_data(instance, ref_data, request=request, is_correction=False)
return instance
class AbsoluteFileField(serializers.FileField): class AbsoluteFileField(serializers.FileField):
def to_representation(self, value): def to_representation(self, value):
if not value: if not value:

4
apps/hadis/views_admin.py

@ -329,7 +329,7 @@ class AdminHadisCorrectionViewSet(ModelViewSet):
status=True status=True
).values("content_id").annotate(count=Count("id")).values("count") ).values("content_id").annotate(count=Count("id")).values("count")
queryset = HadisCorrection.objects.all().select_related("hadis").annotate(
queryset = HadisCorrection.objects.all().select_related("hadis").prefetch_related("references", "references__images").annotate(
annotated_bookmark_count=Coalesce(Subquery(bookmarks_subquery, output_field=IntegerField()), 0) annotated_bookmark_count=Coalesce(Subquery(bookmarks_subquery, output_field=IntegerField()), 0)
) )
hadis_id = self.request.query_params.get("hadis_id") hadis_id = self.request.query_params.get("hadis_id")
@ -365,7 +365,7 @@ class AdminHadisInterpretationViewSet(ModelViewSet):
pagination_class = None pagination_class = None
def get_queryset(self): def get_queryset(self):
queryset = HadisInterpretation.objects.all().select_related("category")
queryset = HadisInterpretation.objects.all().select_related("category").prefetch_related("references", "references__images")
category_id = self.request.query_params.get("category_id") category_id = self.request.query_params.get("category_id")
if category_id: if category_id:
queryset = queryset.filter(category_id=category_id) queryset = queryset.filter(category_id=category_id)

Loading…
Cancel
Save