diff --git a/apps/hadis/apps.py b/apps/hadis/apps.py index cd72637..4a21e14 100644 --- a/apps/hadis/apps.py +++ b/apps/hadis/apps.py @@ -4,6 +4,6 @@ from django.apps import AppConfig class HadisConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'apps.hadis' - # def ready(self): - # # Import the signals module when the app starts - # # import apps.hadis.signals + def ready(self): + # Import the signals module when the app starts + import apps.hadis.signals diff --git a/apps/hadis/docs.py b/apps/hadis/docs.py index 5b08db0..65817d7 100644 --- a/apps/hadis/docs.py +++ b/apps/hadis/docs.py @@ -249,7 +249,12 @@ hadis_sync_swagger = swagger_auto_schema( "title": "The Merit of Seeking Knowledge", "title_narrator": "Jabir bin Abdullah", "text": "اتَّقِ اللَّهَ حَيْثُمَا كُنْتَ، وَأَتْبِعِ السَّيِّئَةَ الْحَسَنَةَ تَمْحُهَا.", - "translation": "The best among you are those who have the best manners and character.", + "translation": [ + { + "language_code": "en", + "text": "The best among you are those who have the best manners and character." + } + ], "detail": { "address": [ "Sahih al-Bukhari", diff --git a/apps/hadis/serializers/hadis.py b/apps/hadis/serializers/hadis.py index 89f23ea..9185ac8 100644 --- a/apps/hadis/serializers/hadis.py +++ b/apps/hadis/serializers/hadis.py @@ -90,9 +90,9 @@ class HadisSyncSerializer(serializers.ModelSerializer): corrections = serializers.SerializerMethodField() category_slug = serializers.CharField(source='category.slug', read_only=True) interpretations = serializers.SerializerMethodField() - title =LocalizedField() + title = LocalizedField() title_narrator = LocalizedField() - translation = LocalizedField() + translation = serializers.SerializerMethodField() class Meta: model = Hadis @@ -103,6 +103,9 @@ class HadisSyncSerializer(serializers.ModelSerializer): 'detail', 'narrators', 'explanations', 'corrections', 'interpretations' ] + def get_translation(self, obj): + return obj.translation or [] + def get_detail(self, obj): request = self.context.get('request') diff --git a/apps/hadis/signals.py b/apps/hadis/signals.py index dd61a7f..6e9d506 100644 --- a/apps/hadis/signals.py +++ b/apps/hadis/signals.py @@ -1,33 +1,44 @@ -# hadith_app/signals.py - -from django.db.models.signals import post_save, post_delete -from django.dispatch import receiver -from django.core.cache import cache -from .models import * - -# 1. Define all models that affect the list -# If a Category title changes, the list must update. -# If a Status changes, the list must update. -TARGET_MODELS = [Hadis , HadisCategory , HadisCollection , HadisCorrection , HadisInCollection , HadisReference , - HadisSect , HadisStatus , HadisTag , HadisTransmitter , Transmitters ,TransmitterOpinion , TransmitterReliability, - TransmitterOriginalText,ReferenceImage , BookReference , BookAttribute, BookAuthor ,BookReferenceImage, - NarratorLayer , OpinionStatus ] - -@receiver(post_save) -@receiver(post_delete) -def clear_hadis_cache(sender, instance, **kwargs): - """ - Clears the API cache whenever a Hadith or related model is saved/deleted. - """ - if sender in TARGET_MODELS: - # This is the magic command from django-redis - # It finds ALL keys starting with the prefix and deletes them - # *:1: is the default django version prefix - try: - # Delete any key that contains our prefix "hadis_api" - # The pattern "*hadis_api*" ensures we catch all variations (headers, pages, etc) - cache.delete_pattern("*hadis_api*") - print(f"Cache cleared for {sender.__name__} update!") - except Exception as e: - # Fail silently or log error, don't crash the save transaction - print(f"Cache clear failed: {e}") \ No newline at end of file +# hadith_app/signals.py + +from django.db.models.signals import post_save, post_delete +from django.dispatch import receiver +from django.core.cache import cache +from .models import * + +# 1. Define all models that affect the list +# If a Category title changes, the list must update. +# If a Status changes, the list must update. +TARGET_MODELS = [ + Hadis, HadisCategory, HadisCollection, HadisCorrection, HadisInCollection, HadisReference, + HadisSect, HadisStatus, HadisTag, HadisTransmitter, Transmitters, TransmitterOpinion, TransmitterReliability, + TransmitterOriginalText, ReferenceImage, BookReference, BookAttribute, BookAuthor, BookReferenceImage, + NarratorLayer, OpinionStatus, ContentRelease +] + + +def invalidate_hadis_cache(): + """ + Deletes all Redis cache keys matching '*hadis_api*'. + Falls back to cache.clear() if cache backend doesn't support delete_pattern. + """ + try: + if hasattr(cache, 'delete_pattern'): + deleted = cache.delete_pattern("*hadis_api*") + print(f"Cache cleared for hadis_api (deleted {deleted} keys)!") + else: + cache.clear() + print("Cache cleared for hadis_api (fallback clear)!") + except Exception as e: + # Fail silently or log error, don't crash the transaction + print(f"Cache clear failed: {e}") + + +@receiver(post_save) +@receiver(post_delete) +def clear_hadis_cache(sender, instance, **kwargs): + """ + Clears the API cache whenever a Hadith or related model is saved/deleted. + """ + if sender in TARGET_MODELS: + invalidate_hadis_cache() + print(f"Cache cleared for {sender.__name__} update!") \ No newline at end of file diff --git a/apps/hadis/views_admin.py b/apps/hadis/views_admin.py index 9fef2a7..34cf8f3 100644 --- a/apps/hadis/views_admin.py +++ b/apps/hadis/views_admin.py @@ -968,6 +968,9 @@ class AdminContentReleaseViewSet(ModelViewSet): is_active=True ) + from .signals import invalidate_hadis_cache + invalidate_hadis_cache() + return Response({ "status": "success", "message": f"Version incremented to {version_name}", @@ -975,3 +978,19 @@ class AdminContentReleaseViewSet(ModelViewSet): "next_suggested_version": compute_next_version(version_name) }) + def perform_create(self, serializer): + super().perform_create(serializer) + from .signals import invalidate_hadis_cache + invalidate_hadis_cache() + + def perform_update(self, serializer): + super().perform_update(serializer) + from .signals import invalidate_hadis_cache + invalidate_hadis_cache() + + def perform_destroy(self, instance): + super().perform_destroy(instance) + from .signals import invalidate_hadis_cache + invalidate_hadis_cache() + +