You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

310 lines
13 KiB

from rest_framework import generics
from ..models import BookReference
from ..serializers.reference_v2 import BookReferenceV2DetailSerializer
from drf_yasg.utils import swagger_auto_schema
class BookReferenceV2DetailView(generics.RetrieveAPIView):
"""
V2 View to retrieve Book Reference details, formatted with tabs
(Information, Excerpts, Volumes) and supporting multiple editions per book.
"""
queryset = BookReference.objects.all()
serializer_class = BookReferenceV2DetailSerializer
lookup_field = 'slug'
def get_queryset(self):
return (
BookReference.objects
.filter(slug=self.kwargs.get('slug'))
.prefetch_related(
'authors',
'editions__volumes__images',
'volumes__images',
'images',
'hadis_references__hadis'
)
)
@swagger_auto_schema(
operation_summary="Get V2 Book Reference Detail",
operation_description="Retrieve structured metadata for a book reference, including its editions, related hadiths (excerpts), and volumes.",
tags=['Dobodbi - Hadis (V2)'],
responses={200: BookReferenceV2DetailSerializer}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
from utils.pagination import NoPagination
from ..serializers.reference_v2 import BookReferenceV2SyncSerializer
class BookReferenceV2SyncView(generics.ListAPIView):
"""
API view to sync all V2 book reference data for offline mode
Returns all book references with editions, volumes, and related hadises
"""
serializer_class = BookReferenceV2SyncSerializer
pagination_class = NoPagination
@swagger_auto_schema(
operation_summary="Sync V2 Book References",
operation_description="Returns all book references for offline sync.",
tags=['Dobodbi - Hadis (V2)'],
responses={200: BookReferenceV2SyncSerializer(many=True)}
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
qs = BookReference.objects.select_related().prefetch_related(
'authors', 'attributes', 'images', 'editions__volumes', 'volumes', 'hadis_references__hadis'
).distinct().order_by('id')
category = self.request.query_params.get('category')
if category:
qs = qs.filter(subject_area__id=category)
author = self.request.query_params.get('author')
if author:
qs = qs.filter(authors__id=author)
sect = self.request.query_params.get('sect')
if sect:
qs = qs.filter(type__id=sect)
pdf_available = self.request.query_params.get('pdf_available')
if pdf_available == 'true':
qs = qs.filter(documents__isnull=False)
elif pdf_available == 'false':
qs = qs.filter(documents__isnull=True)
century = self.request.query_params.get('century')
if century:
if century == 'before_islam':
qs = qs.filter(authors__death_year_hijri__lt=0)
elif century.isdigit():
century_num = int(century)
start_year = (century_num - 1) * 100 + 1
end_year = century_num * 100
qs = qs.filter(authors__death_year_hijri__gte=start_year, authors__death_year_hijri__lte=end_year)
return qs
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
categories_qs = BookSubjectArea.objects.all()
categories = [{"id": c.id, "title": get_localized_text(c.title, request)} for c in categories_qs]
sects_qs = BookType.objects.all()
sects = [{"id": s.id, "title": get_localized_text(s.title, request)} for s in sects_qs]
filters_metadata = {
"categories": categories,
"madhab": sects
}
return Response({
"count": queryset.count(),
"filters": filters_metadata,
"results": serializer.data
})
from rest_framework.response import Response
from ..serializers.reference_v2 import BookReferenceV2ListSerializer
from ..models import BookAuthor, BookSubjectArea, BookType
from utils.pagination import StandardResultsSetPagination
from ..serializers.category import get_localized_text
from drf_yasg import openapi
class BookReferenceV2ListView(generics.ListAPIView):
"""
API view to list V2 book references with filters and metadata
"""
serializer_class = BookReferenceV2ListSerializer
pagination_class = StandardResultsSetPagination
@swagger_auto_schema(
operation_summary="List V2 Book References with Filters",
operation_description="Returns a paginated list of book references and available filters (categories, sects).\n"
"Use query parameters to filter the results.",
tags=['Dobodbi - Hadis (V2)'],
manual_parameters=[
openapi.Parameter('category', openapi.IN_QUERY, description="Filter by Category/Subject Area ID", type=openapi.TYPE_INTEGER),
openapi.Parameter('author', openapi.IN_QUERY, description="Filter by Author ID", type=openapi.TYPE_INTEGER),
openapi.Parameter('madhab', openapi.IN_QUERY, description="Filter by Madhab ('shia' or 'sunni') or Type ID", type=openapi.TYPE_STRING, enum=['shia', 'sunni']),
openapi.Parameter('pdf_available', openapi.IN_QUERY, description="Filter by PDF availability ('true' or 'false')", type=openapi.TYPE_STRING),
openapi.Parameter('century', openapi.IN_QUERY, description="Filter by Century (e.g. '1', '2', 'before_islam')", type=openapi.TYPE_STRING),
openapi.Parameter('search', openapi.IN_QUERY, description="Search term for book title, description, or author name", type=openapi.TYPE_STRING),
]
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
qs = BookReference.objects.prefetch_related('authors', 'tags', 'volumes__images').distinct().order_by('-created_at')
search = self.request.query_params.get('search')
if search:
from django.db.models import Q
qs = qs.filter(
Q(title__icontains=search) |
Q(description__icontains=search) |
Q(authors__name__icontains=search)
)
category = self.request.query_params.get('category')
if category:
qs = qs.filter(subject_area__id=category)
author = self.request.query_params.get('author')
if author:
qs = qs.filter(authors__id=author)
madhab = self.request.query_params.get('madhab')
if madhab:
if madhab in ['shia', 'sunni']:
qs = qs.filter(type__sect=madhab)
else:
qs = qs.filter(type__id=madhab)
pdf_available = self.request.query_params.get('pdf_available')
if pdf_available == 'true':
qs = qs.filter(documents__isnull=False)
elif pdf_available == 'false':
qs = qs.filter(documents__isnull=True)
century = self.request.query_params.get('century')
if century:
if century == 'before_islam':
qs = qs.filter(authors__death_year_hijri__lt=0)
elif century.isdigit():
century_num = int(century)
start_year = (century_num - 1) * 100 + 1
end_year = century_num * 100
qs = qs.filter(authors__death_year_hijri__gte=start_year, authors__death_year_hijri__lte=end_year)
return qs
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(page if page is not None else queryset, many=True)
categories_qs = BookSubjectArea.objects.all()
categories = [{"id": c.id, "title": get_localized_text(c.title, request)} for c in categories_qs]
sects_qs = BookType.objects.all()
sects = [{"id": s.id, "title": get_localized_text(s.title, request)} for s in sects_qs]
filters_metadata = {
"categories": categories,
"madhab": sects
}
if page is not None:
response = self.get_paginated_response(serializer.data)
# Add filters directly into the response dict
response.data['filters'] = filters_metadata
return response
return Response({
"filters": filters_metadata,
"results": serializer.data
})
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.permissions import AllowAny
from rest_framework.filters import SearchFilter
from utils.pagination import StandardResultsSetPagination
from apps.hadis.models.reference import BookAuthor, BookReference
from apps.hadis.serializers.reference_v2 import (
BookAuthorListSerializer,
BookAuthorDetailSerializer,
AuthorBookReferenceSerializer,
BookAuthorSyncSerializer
)
class BookAuthorListView(ListAPIView):
"""
لیست تمام نویسندگان رفرنس
"""
queryset = BookAuthor.objects.all().order_by('-created_at')
serializer_class = BookAuthorListSerializer
pagination_class = StandardResultsSetPagination
permission_classes = [AllowAny]
filter_backends = [SearchFilter]
search_fields = ['name', 'known_as', 'scholarity', 'tabaqa', 'rutba', 'features']
@swagger_auto_schema(
operation_summary="List Book Authors",
operation_description="Returns a paginated list of book authors.",
tags=['Dobodbi - Hadis (V2)'],
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
class BookAuthorDetailView(RetrieveAPIView):
"""
دریافت اطلاعات دقیق یک نویسنده بر اساس slug
"""
queryset = BookAuthor.objects.select_related('related_narrator').all()
serializer_class = BookAuthorDetailSerializer
lookup_field = 'slug'
lookup_url_kwarg = 'author_slug'
permission_classes = [AllowAny]
@swagger_auto_schema(
operation_summary="Book Author Detail",
operation_description="Returns detailed information about a specific book author.",
tags=['Dobodbi - Hadis (V2)'],
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
class AuthorReferencesListView(ListAPIView):
"""
لیست تمام رفرنس‌ها (کتاب‌ها)یی که این نویسنده در آن‌ها تگ شده است
"""
serializer_class = AuthorBookReferenceSerializer
pagination_class = StandardResultsSetPagination
permission_classes = [AllowAny]
@swagger_auto_schema(
operation_summary="Author References List",
operation_description="Returns a paginated list of book references for a specific author.",
tags=['Dobodbi - Hadis (V2)'],
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)
def get_queryset(self):
author_slug = self.kwargs.get('author_slug')
# پیدا کردن رفرنس‌هایی که این نویسنده جزو authors آن‌هاست
return BookReference.objects.filter(
authors__slug=author_slug
).prefetch_related('authors', 'images').distinct().order_by('-created_at')
class BookAuthorSyncView(generics.ListAPIView):
"""
API view to sync all Book Authors data for offline mode.
Returns complete author data and their associated books without pagination.
"""
# 👇 استفاده از prefetch_related برای جلوگیری از کرش کردن دیتابیس به خاطر N+1 Query
queryset = BookAuthor.objects.select_related('related_narrator').prefetch_related('book_references').order_by('id')
serializer_class = BookAuthorSyncSerializer
pagination_class = NoPagination
permission_classes = [AllowAny]
@swagger_auto_schema(
operation_summary="Sync Book Authors",
operation_description="Returns complete book authors data including their books for offline sync.",
tags=['Dobodbi - Hadis (V2)'],
)
def get(self, request, *args, **kwargs):
return super().get(request, *args, **kwargs)