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.
306 lines
12 KiB
306 lines
12 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',
|
|
'volumes',
|
|
'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('sect', openapi.IN_QUERY, description="Filter by Sect/Type ID", type=openapi.TYPE_INTEGER),
|
|
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').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)
|
|
|
|
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())
|
|
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)
|