Browse Source

feat(hadis): add bulk delete endpoint for admin hadis reference images

master
Mohsen Taba 3 weeks ago
parent
commit
021085b866
  1. 25
      apps/hadis/serializers/serializers_admin.py
  2. 3
      apps/hadis/urls.py
  3. 83
      apps/hadis/views_admin.py

25
apps/hadis/serializers/serializers_admin.py

@ -6,7 +6,7 @@ from django.db.models import Exists, OuterRef
from utils.image_compression import maybe_compress_uploaded_file
from utils import absolute_https_url
from ..models import (
Hadis, HadisCategory, HadisStatus, HadisTag, HadisCorrection, HadisInterpretation, HadisCollection, HadisSect, HadisInCollection, HadisTransmitter, HadisReference,
Hadis, HadisCategory, HadisStatus, HadisTag, HadisCorrection, HadisInterpretation, HadisCollection, HadisSect, HadisInCollection, HadisTransmitter, HadisReference, ReferenceImage,
BookReference, BookReferenceImage, BookReferenceDocument, BookAuthor, BookAttribute, BookSubjectArea, BookType, BookTag, BookEdition, BookVolume, BookResearcher, BookEditor,
Transmitters, TransmitterReliability, NarratorLayer, OpinionStatus, TransmitterOpinion, TransmitterOriginalText,
CorrectionReference, CorrectionReferenceImage, InterpretationReference, InterpretationReferenceImage,
@ -325,6 +325,20 @@ class AdminHadisDetailSerializer(serializers.ModelSerializer):
}
else:
ret["book_reference_detail"] = None
ref_images = []
for r in refs:
for img in r.images.all().order_by("priority", "id"):
url = absolute_https_url(img.thumbnail.url, self.context.get("request")) if img.thumbnail else None
ref_images.append({
"id": img.id,
"reference_id": r.id,
"hadis_id": instance.id,
"thumbnail": url,
"image": url,
"priority": img.priority,
})
ret["reference_images"] = ref_images
return ret
def get_bookmark_count(self, obj):
@ -1214,6 +1228,15 @@ class AdminBookReferenceImageSerializer(serializers.ModelSerializer):
return obj.book_volume.title if getattr(obj, 'book_volume', None) else ""
class AdminHadisReferenceImageSerializer(serializers.ModelSerializer):
thumbnail = AbsoluteImageField(required=True)
hadis_id = serializers.IntegerField(source="reference.hadis_id", read_only=True)
class Meta:
model = ReferenceImage
fields = ["id", "reference", "hadis_id", "thumbnail", "priority"]
class AdminBookReferenceDocumentSerializer(serializers.ModelSerializer):
file = AbsoluteFileField(required=True)
volume = serializers.SerializerMethodField()

3
apps/hadis/urls.py

@ -15,7 +15,7 @@ from .views.version import ContentReleaseSyncView
from .views.info import HadisInfoView
from .views_admin import (
AdminHadisCategoryViewSet, AdminHadisViewSet, AdminHadisCorrectionViewSet, AdminHadisInterpretationViewSet, AdminHadisStatusViewSet, AdminHadisTagViewSet, AdminHadisCollectionViewSet,
AdminBookSubjectAreaViewSet, AdminBookTypeViewSet, AdminBookTagViewSet, AdminBookAuthorViewSet, AdminBookAttributeViewSet, AdminBookReferenceImageViewSet, AdminBookReferenceDocumentViewSet, AdminBookReferenceViewSet,
AdminBookSubjectAreaViewSet, AdminBookTypeViewSet, AdminBookTagViewSet, AdminBookAuthorViewSet, AdminBookAttributeViewSet, AdminBookReferenceImageViewSet, AdminHadisReferenceImageViewSet, AdminBookReferenceDocumentViewSet, AdminBookReferenceViewSet,
AdminTransmitterViewSet, AdminTransmitterReliabilityViewSet, DovodiBookSubjectAreaViewSet, DovodiBookTypeViewSet,
DovodiNarratorLayerViewSet, DovodiTransmitterReliabilityViewSet, DovodiOpinionStatusViewSet,
DovodiHadisSectViewSet, DovodiHadisCategoryViewSet, AdminCategoryQuranVerseViewSet, AdminHadisTransmitterViewSet,
@ -50,6 +50,7 @@ admin_router.register(r'dovodi-book-types', DovodiBookTypeViewSet, basename='dov
admin_router.register(r'book-authors', AdminBookAuthorViewSet, basename='admin-book-authors')
admin_router.register(r'book-attributes', AdminBookAttributeViewSet, basename='admin-book-attributes')
admin_router.register(r'book-images', AdminBookReferenceImageViewSet, basename='admin-book-images')
admin_router.register(r'hadis-reference-images', AdminHadisReferenceImageViewSet, basename='admin-hadis-reference-images')
admin_router.register(r'book-documents', AdminBookReferenceDocumentViewSet, basename='admin-book-documents')
admin_router.register(r'transmitters', AdminTransmitterViewSet, basename='admin-transmitters')
admin_router.register(r'transmitter-reliabilities', AdminTransmitterReliabilityViewSet, basename='admin-transmitter-reliabilities')

83
apps/hadis/views_admin.py

@ -10,7 +10,7 @@ from apps.account.permissions import IsSuperAdmin
from utils.pagination import StandardResultsSetPagination, OptionalPagination
from .models import (
Hadis, HadisCategory, HadisCollection, HadisInCollection, HadisCorrection, HadisInterpretation, HadisStatus, HadisTag, HadisSect, HadisTransmitter,
Hadis, HadisCategory, HadisCollection, HadisInCollection, HadisCorrection, HadisInterpretation, HadisStatus, HadisTag, HadisSect, HadisTransmitter, HadisReference, ReferenceImage,
BookReference, BookReferenceImage, BookReferenceDocument, BookAuthor, BookAttribute, BookSubjectArea, BookType, BookTag, BookEdition, BookVolume,
Transmitters, TransmitterReliability, NarratorLayer, OpinionStatus, TransmitterOpinion, TransmitterOriginalText,
ContentRelease
@ -34,6 +34,7 @@ from .serializers.serializers_admin import (
AdminBookAuthorSerializer,
AdminBookAttributeSerializer,
AdminBookReferenceImageSerializer,
AdminHadisReferenceImageSerializer,
AdminBookReferenceDocumentSerializer,
AdminBookReferenceListSerializer,
AdminBookReferenceDetailSerializer,
@ -587,6 +588,86 @@ class AdminBookReferenceImageViewSet(ModelViewSet):
return Response({"status": "success"})
class AdminHadisReferenceImageViewSet(ModelViewSet):
serializer_class = AdminHadisReferenceImageSerializer
permission_classes = [IsAuthenticated, IsSuperAdmin]
authentication_classes = [TokenAuthentication]
parser_classes = (MultiPartParser, FormParser, JSONParser)
pagination_class = None
def get_queryset(self):
queryset = ReferenceImage.objects.all().select_related("reference")
hadis_id = self.request.query_params.get("hadis_id")
if hadis_id:
queryset = queryset.filter(reference__hadis_id=hadis_id)
reference_id = self.request.query_params.get("reference_id")
if reference_id:
queryset = queryset.filter(reference_id=reference_id)
return queryset.order_by("priority", "id")
def create(self, request, *args, **kwargs):
hadis_id = request.data.get("hadis_id")
reference_id = request.data.get("reference_id")
thumbnail = request.FILES.get("thumbnail") or request.FILES.get("image")
priority = request.data.get("priority", 0)
if not thumbnail:
return Response({"error": "thumbnail image is required"}, status=400)
if hadis_id:
try:
hadis = Hadis.objects.get(id=hadis_id)
except Hadis.DoesNotExist:
return Response({"error": "Hadis not found"}, status=404)
reference = hadis.references.first()
if not reference:
reference = HadisReference.objects.create(hadis=hadis)
elif reference_id:
try:
reference = HadisReference.objects.get(id=reference_id)
except HadisReference.DoesNotExist:
return Response({"error": "HadisReference not found"}, status=404)
else:
return Response({"error": "hadis_id or reference_id is required"}, status=400)
if not priority:
last_img = reference.images.order_by("-priority").first()
priority = (last_img.priority + 1) if last_img else 1
else:
try:
priority = int(priority)
except (ValueError, TypeError):
priority = 1
ref_image = ReferenceImage.objects.create(
reference=reference,
thumbnail=thumbnail,
priority=priority
)
serializer = self.get_serializer(ref_image)
return Response(serializer.data, status=201)
@action(detail=False, methods=["post"])
def reorder(self, request):
image_ids = request.data.get("image_ids", []) or request.data.get("ids", [])
if not image_ids:
return Response({"error": "image_ids list is required"}, status=400)
for index, img_id in enumerate(image_ids, start=1):
ReferenceImage.objects.filter(id=img_id).update(priority=index)
return Response({"status": "success"})
@action(detail=False, methods=["post"])
def bulk_delete(self, request):
image_ids = request.data.get("ids", []) or request.data.get("image_ids", [])
if not image_ids:
return Response({"error": "ids list is required"}, status=400)
deleted_count, _ = ReferenceImage.objects.filter(id__in=image_ids).delete()
return Response({"status": "success", "deleted_count": deleted_count})
class AdminBookReferenceDocumentViewSet(ModelViewSet):
serializer_class = AdminBookReferenceDocumentSerializer
permission_classes = [IsAuthenticated, IsSuperAdmin]

Loading…
Cancel
Save