|
|
|
@ -5,7 +5,8 @@ from utils.image_compression import maybe_compress_uploaded_file |
|
|
|
from ..models import ( |
|
|
|
Hadis, HadisCategory, HadisStatus, HadisTag, HadisCorrection, HadisInterpretation, HadisCollection, HadisSect, HadisInCollection, HadisTransmitter, |
|
|
|
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 |
|
|
|
|
|
|
|
@ -244,10 +245,62 @@ class AdminHadisCategoryBriefSerializer(serializers.ModelSerializer): |
|
|
|
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): |
|
|
|
hadis_detail = AdminHadisBriefSerializer(source="hadis", 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: |
|
|
|
model = HadisCorrection |
|
|
|
fields = [ |
|
|
|
@ -260,15 +313,113 @@ class AdminHadisCorrectionSerializer(serializers.ModelSerializer): |
|
|
|
"translation", |
|
|
|
"priority", |
|
|
|
"bookmark_count", |
|
|
|
"links", |
|
|
|
"book_reference_id", |
|
|
|
"address", |
|
|
|
"delete_image_ids", |
|
|
|
"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): |
|
|
|
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: |
|
|
|
model = HadisInterpretation |
|
|
|
fields = [ |
|
|
|
@ -279,11 +430,90 @@ class AdminHadisInterpretationSerializer(serializers.ModelSerializer): |
|
|
|
"text", |
|
|
|
"translation", |
|
|
|
"priority", |
|
|
|
"links", |
|
|
|
"book_reference_id", |
|
|
|
"address", |
|
|
|
"delete_image_ids", |
|
|
|
"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): |
|
|
|
def to_representation(self, value): |
|
|
|
if not value: |
|
|
|
|