Browse Source

hadis filters endpoint added

master
Mohsen Taba 1 month ago
parent
commit
bcd515ea9d
  1. 3
      apps/hadis/urls.py
  2. 156
      apps/hadis/views/hadis.py
  3. 2
      entrypoint.sh

3
apps/hadis/urls.py

@ -1,6 +1,6 @@
from django.urls import path
from .views.category import HadisCategorySectListView, HadisCategoryTreeView, CategoriesView, CategoriesBySectView, HadisCategorySelectBySectView, HadisCategorySelectBySectSourceView , HadisCategoryTreeNormalView ,test_deploy,debug_headers,HadisCategoryXMindView
from .views.hadis import HadisCollectionListView, HadisListView, HadisBasicView, HadisDetailView, HadisSyncView, HadisTransmittersView, HadisCorrectionsView,HadisMainListView, HadisFiltersView, HadisLayersView,PinnedHadisCollectionListView
from .views.hadis import HadisCollectionListView, HadisListView, HadisBasicView, HadisDetailView, HadisSyncView, HadisTransmittersView, HadisCorrectionsView,HadisMainListView, HadisFiltersView, HadisLayersView,PinnedHadisCollectionListView, HadisFiltersSyncAPIView
from .views.transmitter import TransmitterView ,TransmitterDetailView, TransmitterSyncView,TransmitterOpinionView, TransmitterOriginalTextView, TransmitterFiltersView
from .views.reference import BookDetailView, BookReferencesView, BookReferenceSyncView, BookAttributeView
from .views.version import ContentReleaseSyncView
@ -23,6 +23,7 @@ urlpatterns = [
path('sync/narrators/', TransmitterSyncView.as_view(), name='transmitter-sync'),
path('sync/references/', BookReferenceSyncView.as_view(), name='reference-sync'),
path('sync/version/', ContentReleaseSyncView.as_view(), name='content-release-sync'),
path('sync/filters/', HadisFiltersSyncAPIView.as_view(), name='hadis-filters-sync'),
path('info/', HadisInfoView.as_view(), name='hadis-info'),
# Category paths (more specific first)

156
apps/hadis/views/hadis.py

@ -620,3 +620,159 @@ class HadisFiltersView(ListAPIView):
}
return Response(response_data)
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from rest_framework.authentication import TokenAuthentication
from drf_yasg.utils import swagger_auto_schema
from django.utils.translation import get_language
from apps.hadis.models import HadisStatus, HadisCategory, BookReference, Transmitters
from drf_yasg import openapi
class HadisFiltersSyncAPIView(APIView):
"""
API view to return all filter data for hadis (Sync API for Mobile App)
Returns statuses, categories, sources (books), and narrators.
Optimized for offline client-side searching and sorting.
"""
permission_classes = [AllowAny]
authentication_classes = [TokenAuthentication]
@swagger_auto_schema(
operation_description=(
"Sync API for Flutter/mobile clients: returns flat hadis filter data for offline "
"searching and local filtering. Titles are localized from multilingual fields based "
"on the active request language."
),
operation_summary="Sync Hadis Filters",
tags=['Dobodbi - Hadis'],
manual_parameters=[
openapi.Parameter(
'Accept-Language',
openapi.IN_HEADER,
description="Language code for localized titles, for example `en`, `fa`, `ar`, `ur`, or `ru`.",
type=openapi.TYPE_STRING,
required=False,
)
],
responses={
status.HTTP_200_OK: openapi.Response(
description="Flat filter payload for hadis categories, statuses, sources, and narrators.",
examples={
"application/json": {
"statuses": [
{
"id": 133,
"slug": "sahih",
"title": "Authentic",
"order": 1,
"color": "green",
"main_color_code": "#1DAC43"
}
],
"categories": [
{
"id": 1036,
"slug": "general-hadiths",
"title": "General Hadiths",
"order": 1
}
],
"sources": [
{
"id": 2538,
"slug": "man-la-yahduruhu-al-faqih",
"title": "Man La Yahduruhu al-Faqih",
"search_keywords": "Shaykh al-Saduq"
}
],
"narrators": [
{
"id": 501,
"slug": "muhammad-ibn-muslim",
"title": "Muhammad ibn Muslim",
"search_aliases": "Abu Ja'far"
}
]
}
}
)
}
)
def get(self, request, *args, **kwargs):
# تشخیص زبان برای ارسال دیتای لوکالایز شده
lang = getattr(request, "LANGUAGE_CODE", None) or get_language() or "ru"
# ۱. استتوس‌ها (مرتب‌شده بر اساس فیلد order)
statuses = [
{
"id": status.id,
"slug": status.slug,
"title": get_localized_text(status.title, request=request, language_code=lang) or "",
"order": status.order,
"color": status.color,
"main_color_code": status.main_color_code,
}
for status in HadisStatus.objects.all().order_by('order')
]
# ۲. دسته‌بندی‌ها (مرتب‌شده بر اساس فیلد order)
categories = [
{
"id": cat.id,
"slug": cat.slug,
"title": get_localized_text(cat.title, request=request, language_code=lang) or "",
"order": cat.order,
}
for cat in HadisCategory.objects.all().order_by('order')
]
# ۳. منابع / کتاب‌ها
sources = []
# استفاده از prefetch_related برای جلوگیری از مشکل N+1 Query هنگام گرفتن نویسنده‌ها
books = BookReference.objects.prefetch_related('authors').all().order_by('order', '-id')
for book in books:
# استخراج نام نویسنده‌ها برای سرچ آفلاین فلاتر
authors_names = [
get_localized_text(author.name, request=request, language_code=lang) or ""
for author in book.authors.all()
]
sources.append({
"id": book.id,
"slug": book.slug,
"title": get_localized_text(book.title, request=request, language_code=lang) or "",
# تمام اسم‌های نویسنده‌ها را به هم می‌چسبانیم تا فلاتر بتواند روی آن‌ها سرچ بزند
"search_keywords": " ".join(authors_names).strip()
})
# ۴. راویان (نریتورها)
narrators = []
transmitters = Transmitters.objects.all().order_by('id')
for narrator in transmitters:
# گرفتن نام‌های مستعار
known_as = get_localized_text(narrator.known_as, request=request, language_code=lang) or ""
nickname = get_localized_text(narrator.nickname, request=request, language_code=lang) or ""
kunya = get_localized_text(narrator.kunya, request=request, language_code=lang) or ""
# تجمیع نام‌های جایگزین
search_aliases = f"{known_as} {nickname} {kunya}".strip()
narrators.append({
"id": narrator.id,
"slug": narrator.slug,
"title": get_localized_text(narrator.full_name, request=request, language_code=lang) or "",
# فلاتر روی این فیلد + title سرچ می‌زند
"search_aliases": search_aliases
})
# خروجی نهایی بدون پجینیشن
return Response({
"statuses": statuses,
"categories": categories,
"sources": sources,
"narrators": narrators
})

2
entrypoint.sh

@ -5,7 +5,7 @@ python manage.py migrate
# python manage.py seed_images
# python manage.py compilemessages
python manage.py collectstatic --noinput
python manage.py set_hadiscorrection_fixed_text
# python manage.py set_hadiscorrection_fixed_text
# Seed Russian data (only runs once, skips if data exists)
# python manage.py seed_corrections
# python manage.py seed_russian_data

Loading…
Cancel
Save