From 394a06dd92d9da24dff154d620c9be5f853f3164 Mon Sep 17 00:00:00 2001 From: mohsentaba Date: Tue, 23 Dec 2025 13:16:53 +0330 Subject: [PATCH] argument filter url added . arguments url updated. --- apps/hadis/docs.py | 97 +++++++++++++++++++ .../hadis/migrations/0073_hadisstatus_slug.py | 19 ++++ .../migrations/0074_alter_hadisstatus_slug.py | 19 ++++ apps/hadis/models/hadis.py | 9 +- apps/hadis/urls.py | 3 +- apps/hadis/views/hadis.py | 58 ++++++++--- 6 files changed, 190 insertions(+), 15 deletions(-) create mode 100644 apps/hadis/migrations/0073_hadisstatus_slug.py create mode 100644 apps/hadis/migrations/0074_alter_hadisstatus_slug.py diff --git a/apps/hadis/docs.py b/apps/hadis/docs.py index f76e180..7df551e 100644 --- a/apps/hadis/docs.py +++ b/apps/hadis/docs.py @@ -385,6 +385,103 @@ hadis_list_swagger = swagger_auto_schema( ) +arguments_filters_swagger = swagger_auto_schema( + operation_description=""" + Retrieve a paginated list of Hadis (traditions) for a specific category. + + **Key Features:** + - Returns hadis entries filtered by category ID + - Supports pagination for large datasets + - Translations are automatically provided based on the Accept-Language header + - Each hadis includes its category information, title, narrator, Arabic text, and translation + + **Usage:** + - Use this endpoint to browse hadis within a specific category + - The response includes pagination links (next/previous) for navigation + - Set the Accept-Language header to get translations in your preferred language (en, fa, ar, ur) + - Only active (status=True) hadis are returned + + **Response Structure:** + - `count`: Total number of hadis in the category + - `next`: URL for the next page (null if on last page) + - `previous`: URL for the previous page (null if on first page) + - `results`: Array of hadis objects with full details + """, + operation_summary="List Hadis by Category", + tags=['Hadis'], + manual_parameters=[ + openapi.Parameter( + 'Accept-Language', + openapi.IN_HEADER, + description="Language code for translations. Supported codes: 'en' (English), 'fa' (Persian), 'ar' (Arabic), 'ur' (Urdu). Defaults to 'en' if not specified.", + type=openapi.TYPE_STRING, + required=False, + default='en', + enum=['en', 'fa', 'ar', 'ur'] + ) + ], + responses={ + status.HTTP_200_OK: openapi.Response( + description="Successfully retrieved paginated list of hadis for the specified category", + examples={ + "application/json": { + "count": 150, + "next": "http://example.com/api/hadis/category/1/?page=2", + "previous": None, + "results": [ + { + "statuses": [ + { + "text": "Достоверный", + "slug": "-0" + }, + { + "text": "Authentic / Accepted", + "slug": "authentic-accepted-1" + }, + { + "text": "Weak / Needs Review", + "slug": "weak-needs-review-2" + }, + { + "text": "Хороший", + "slug": "-3" + }, + ], + "categories": [ + { + "text": "Толкование суры Аль-Фатиха", + "slug": "-330" + }, + { + "text": "Аяты о молитве", + "slug": "-15" + }, + { + "text": "Истории пророков", + "slug": "-14" + }, + ] + } + ] + } + } + ), + status.HTTP_404_NOT_FOUND: openapi.Response( + description="The specified category ID does not exist or the category has no active hadis", + examples={ + "application/json": { + "detail": "Not found." + } + } + ), + status.HTTP_500_INTERNAL_SERVER_ERROR: openapi.Response( + description="Internal server error occurred while processing the request" + ) + } +) + + hadis_basic_swagger = swagger_auto_schema( operation_description="Get basic information about a specific hadis including core text and translation", operation_summary="Get Hadis Basic Info", diff --git a/apps/hadis/migrations/0073_hadisstatus_slug.py b/apps/hadis/migrations/0073_hadisstatus_slug.py new file mode 100644 index 0000000..c615bac --- /dev/null +++ b/apps/hadis/migrations/0073_hadisstatus_slug.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.27 on 2025-12-23 12:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("hadis", "0072_transmitterreliability_slug"), + ] + + operations = [ + migrations.AddField( + model_name="hadisstatus", + name="slug", + field=models.SlugField( + blank=True, max_length=255, null=True, verbose_name="slug" + ), + ), + ] diff --git a/apps/hadis/migrations/0074_alter_hadisstatus_slug.py b/apps/hadis/migrations/0074_alter_hadisstatus_slug.py new file mode 100644 index 0000000..97961ae --- /dev/null +++ b/apps/hadis/migrations/0074_alter_hadisstatus_slug.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.27 on 2025-12-23 12:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("hadis", "0073_hadisstatus_slug"), + ] + + operations = [ + migrations.AlterField( + model_name="hadisstatus", + name="slug", + field=models.SlugField( + blank=True, max_length=255, unique=True, verbose_name="slug" + ), + ), + ] diff --git a/apps/hadis/models/hadis.py b/apps/hadis/models/hadis.py index 884ce55..095cc8f 100644 --- a/apps/hadis/models/hadis.py +++ b/apps/hadis/models/hadis.py @@ -1,3 +1,4 @@ +from enum import unique from typing import Optional from django.db import models from django.db.models import F, ForeignKey @@ -133,10 +134,16 @@ class HadisStatus(models.Model): GRAY = 'gray', _('Gray') title = models.JSONField(default = list , verbose_name=_('Title')) - + slug= models.SlugField(max_length=255, verbose_name=_('slug'), blank=True,unique = True) color = models.CharField(max_length=20, choices=ColorChoices.choices, verbose_name=_('color')) order = models.IntegerField(default=0, verbose_name=_('order')) + def save(self, *args, **kwargs): + if not self.slug: + slug = slugify(self.title[0]['text']) + self.slug = slug + super().save(*args, **kwargs) + def __str__(self): return self.title[0]['text'] diff --git a/apps/hadis/urls.py b/apps/hadis/urls.py index 5fbbcde..3d8d1f4 100644 --- a/apps/hadis/urls.py +++ b/apps/hadis/urls.py @@ -1,6 +1,6 @@ from django.urls import path from .views.category import HadisCategorySectListView, HadisCategoryTreeView, CategoriesView, CategoriesBySectView, HadisCategorySelectBySectView, HadisCategorySelectBySectSourceView , HadisCategoryTreeNormalView -from .views.hadis import HadisCollectionListView, HadisListView, HadisBasicView, HadisDetailView, HadisSyncView, HadisTransmittersView, HadisCorrectionsView,HadisMainListView +from .views.hadis import HadisCollectionListView, HadisListView, HadisBasicView, HadisDetailView, HadisSyncView, HadisTransmittersView, HadisCorrectionsView,HadisMainListView, HadisFiltersView from .views.transmitter import TransmitterView ,TransmitterDetailView, TransmitterSyncView,TransmitterOpinionView, TransmitterOriginalTextView, TransmitterFiltersView from .views.reference import BookDetailView, BookReferencesView, BookReferenceSyncView, BookAttributeView from .views.info import HadisInfoView @@ -26,6 +26,7 @@ urlpatterns = [ # Hadis paths path('category//', HadisListView.as_view(), name='hadis-list'), path('arguments/', HadisMainListView.as_view(), name='hadis-main-list'), + path('arguments/filters/', HadisFiltersView.as_view(), name='hadis-filters'), # Narrator paths path('narrators//opinions', TransmitterOpinionView.as_view(), name='narrator-opinions'), diff --git a/apps/hadis/views/hadis.py b/apps/hadis/views/hadis.py index e51a9ae..c07a2fb 100644 --- a/apps/hadis/views/hadis.py +++ b/apps/hadis/views/hadis.py @@ -7,9 +7,9 @@ from django.db.models import Count from django.db.models import Prefetch from ..serializers.category import get_localized_text -from ..models import HadisCategory, Hadis, HadisCollection,HadisTransmitter , HadisCorrection ,HadisReference +from ..models import HadisCategory, Hadis, HadisCollection,HadisTransmitter , HadisCorrection ,HadisReference, HadisStatus from ..serializers import HadisListSerializer, HadisBasicSerializer, HadisDetailSerializer, HadisCollectionListSerializer, HadisSyncSerializer,HadisCorrectionSerializer,HadisTransmitterListSerializer -from ..docs import hadis_list_swagger, hadis_detail_swagger, hadis_collections_swagger, hadis_sync_swagger, hadis_transmitters_swagger, hadis_corrections_swagger, hadis_basic_swagger, hadis_main_list_swagger +from ..docs import arguments_filters_swagger ,hadis_list_swagger, hadis_detail_swagger, hadis_collections_swagger, hadis_sync_swagger, hadis_transmitters_swagger, hadis_corrections_swagger, hadis_basic_swagger, hadis_main_list_swagger class HadisCollectionListView(ListAPIView): @@ -146,24 +146,13 @@ class HadisMainListView(ListAPIView): # Modify the paginated response to include our custom data response_data = paginated_response.data - response_data['categories'] = category_titles - response_data['statuses'] = status_titles return Response(response_data) # Fallback for when pagination is disabled serializer = self.get_serializer(queryset, many=True) - - # Get category titles - category_titles = self.get_category_titles(request) - - # Get status titles - status_titles = self.get_status_titles(request) - response_data = { 'count': queryset.count(), - 'categories': category_titles, - 'statuses': status_titles, 'results': serializer.data } @@ -326,3 +315,46 @@ class HadisCorrectionsView(ListAPIView): return HadisCorrection.objects.filter(hadis=hadis) except Hadis.DoesNotExist: return HadisCorrection.objects.none() + + +class HadisFiltersView(ListAPIView): + """ + API view to return filter data for hadis + Returns statuses and categories for filtering + """ + + @arguments_filters_swagger + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def get_queryset(self): + # This view doesn't need a queryset, it returns computed data + return Hadis.objects.none() + + def list(self, request, *args, **kwargs): + # Get statuses from HadisStatus model + statuses = [] + for status in HadisStatus.objects.all().order_by('order'): + title_text = get_localized_text(status.title, request) + if title_text and status.slug: + statuses.append({ + 'text': title_text, + 'slug': status.slug + }) + + # Get categories from HadisCategory model + categories = [] + for category in HadisCategory.objects.all().order_by('order'): + title_text = get_localized_text(category.title, request) + if title_text and category.slug: + categories.append({ + 'text': title_text, + 'slug': category.slug + }) + + response_data = { + 'statuses': statuses, + 'categories': categories + } + + return Response(response_data)