Browse Source

refactor(hadis): rename correction DB tables and labels to evaluation

- Rename DB tables to hadis_hadisevaluation, hadis_evaluationreference, and hadis_evaluationreferenceimage via db_table and migration 0068

- Update verbose names, bookmark/rate service labels, swagger documentation, and share_link tab query (?tab=evaluations)
master
Mohsen Taba 2 days ago
parent
commit
2717755e25
  1. 2
      apps/bookmark/management/commands/cleanup_orphan_bookmarks.py
  2. 23
      apps/bookmark/migrations/0003_alter_bookmark_service_alter_rate_service.py
  3. 2
      apps/bookmark/models/bookmark.py
  4. 2
      apps/bookmark/models/rate.py
  5. 2
      apps/bookmark/views/bookmark.py
  6. 32
      apps/hadis/docs.py
  7. 4
      apps/hadis/management/commands/seed_corrections.py
  8. 6
      apps/hadis/management/commands/seed_hadis_2.py
  9. 43
      apps/hadis/migrations/0068_alter_correctionreference_options_and_more.py
  10. 21
      apps/hadis/models/hadis.py
  11. 22
      apps/hadis/views/hadis.py

2
apps/bookmark/management/commands/cleanup_orphan_bookmarks.py

@ -29,7 +29,7 @@ class Command(BaseCommand):
Bookmark.ServiceChoices.PODCAST: (Podcast, 'Podcast'), Bookmark.ServiceChoices.PODCAST: (Podcast, 'Podcast'),
Bookmark.ServiceChoices.PODCAST_PLAYLIST: (PodcastPlaylist, 'Podcast Playlist'), Bookmark.ServiceChoices.PODCAST_PLAYLIST: (PodcastPlaylist, 'Podcast Playlist'),
Bookmark.ServiceChoices.HADITH: (Hadis, 'Hadith'), Bookmark.ServiceChoices.HADITH: (Hadis, 'Hadith'),
Bookmark.ServiceChoices.HADITH_CORRECTION: (HadisCorrection, 'Hadith Correction'),
Bookmark.ServiceChoices.HADITH_CORRECTION: (HadisCorrection, 'Hadith Evaluation'),
Bookmark.ServiceChoices.VIDEO: (Video, 'Video'), Bookmark.ServiceChoices.VIDEO: (Video, 'Video'),
Bookmark.ServiceChoices.VIDEO_PLAYLIST: (VideoPlaylist, 'Video Playlist'), Bookmark.ServiceChoices.VIDEO_PLAYLIST: (VideoPlaylist, 'Video Playlist'),
Bookmark.ServiceChoices.ARTICLE: (Article, 'Article'), Bookmark.ServiceChoices.ARTICLE: (Article, 'Article'),

23
apps/bookmark/migrations/0003_alter_bookmark_service_alter_rate_service.py

@ -0,0 +1,23 @@
# Generated by Django 4.2.30 on 2026-10-28 09:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('bookmark', '0002_alter_rate_service'),
]
operations = [
migrations.AlterField(
model_name='bookmark',
name='service',
field=models.CharField(choices=[('library', 'Library'), ('podcast', 'Podcast'), ('podcast_playlist', 'Podcast Playlist'), ('hadith', 'Hadith'), ('hadith_correction', 'Hadith Evaluation'), ('video', 'Video'), ('video_playlist', 'Video Playlist'), ('article', 'Article')], max_length=20, verbose_name='Service'),
),
migrations.AlterField(
model_name='rate',
name='service',
field=models.CharField(choices=[('library', 'Library'), ('podcast', 'Podcast'), ('podcast_playlist', 'Podcast Playlist'), ('hadith', 'Hadith'), ('hadith_correction', 'Hadith Evaluation'), ('video', 'Video'), ('video_playlist', 'Video Playlist'), ('article', 'Article')], max_length=20, verbose_name='Service'),
),
]

2
apps/bookmark/models/bookmark.py

@ -15,7 +15,7 @@ class Bookmark(models.Model):
PODCAST = 'podcast', 'Podcast' PODCAST = 'podcast', 'Podcast'
PODCAST_PLAYLIST = 'podcast_playlist', 'Podcast Playlist' PODCAST_PLAYLIST = 'podcast_playlist', 'Podcast Playlist'
HADITH = 'hadith', 'Hadith' HADITH = 'hadith', 'Hadith'
HADITH_CORRECTION = 'hadith_correction', 'Hadith Correction'
HADITH_CORRECTION = 'hadith_correction', 'Hadith Evaluation'
VIDEO = 'video', 'Video' VIDEO = 'video', 'Video'
VIDEO_PLAYLIST = 'video_playlist', 'Video Playlist' VIDEO_PLAYLIST = 'video_playlist', 'Video Playlist'
ARTICLE = 'article', 'Article' ARTICLE = 'article', 'Article'

2
apps/bookmark/models/rate.py

@ -17,7 +17,7 @@ class Rate(models.Model):
PODCAST = 'podcast', 'Podcast' PODCAST = 'podcast', 'Podcast'
PODCAST_PLAYLIST = 'podcast_playlist', 'Podcast Playlist' PODCAST_PLAYLIST = 'podcast_playlist', 'Podcast Playlist'
HADITH = 'hadith', 'Hadith' HADITH = 'hadith', 'Hadith'
HADITH_CORRECTION = 'hadith_correction', 'Hadith Correction'
HADITH_CORRECTION = 'hadith_correction', 'Hadith Evaluation'
VIDEO = 'video', 'Video' VIDEO = 'video', 'Video'
VIDEO_PLAYLIST = 'video_playlist', 'Video Playlist' VIDEO_PLAYLIST = 'video_playlist', 'Video Playlist'
ARTICLE = 'article', 'Article' ARTICLE = 'article', 'Article'

2
apps/bookmark/views/bookmark.py

@ -25,7 +25,7 @@ class AddBookmarkView(CreateAPIView):
operation_description="Add a bookmark for a specific content in a service.\ operation_description="Add a bookmark for a specific content in a service.\
If the bookmark already exists but is inactive, it will be reactivated.\ If the bookmark already exists but is inactive, it will be reactivated.\
\n Services must be choose from : \n \ \n Services must be choose from : \n \
'Library'\n'Podcast'\n'Podcast Playlist'\n'Hadith' \n 'Hadith Correction'\n'Video'\n'Video Playlist'\n'Article'",
'Library'\n'Podcast'\n'Podcast Playlist'\n'Hadith' \n 'Hadith Evaluation'\n'Video'\n'Video Playlist'\n'Article'",
tags=["Dobodbi - Bookmarks"], tags=["Dobodbi - Bookmarks"],
request_body=BookmarkSerializer, request_body=BookmarkSerializer,
responses={ responses={

32
apps/hadis/docs.py

@ -990,31 +990,31 @@ hadis_transmitters_swagger = swagger_auto_schema(
hadis_corrections_swagger = swagger_auto_schema( hadis_corrections_swagger = swagger_auto_schema(
operation_description=""" operation_description="""
Retrieve all corrections, improvements, and scholarly notes for a specific hadis.
Retrieve all evaluations, improvements, and scholarly notes for a specific hadis.
**Key Features:** **Key Features:**
- Returns all corrections associated with a hadis
- Includes translation corrections in multiple languages
- Returns all evaluations associated with a hadis
- Includes translation evaluations in multiple languages
- Provides scholarly improvements and clarifications - Provides scholarly improvements and clarifications
- Useful for understanding updates and refinements to hadis content - Useful for understanding updates and refinements to hadis content
**Usage:** **Usage:**
- Use this endpoint to get corrections and improvements for a hadis
- Corrections may include updated translations, authenticity clarifications, or scholarly notes
- The `translation` field contains multilingual corrections (typically JSON format)
- Each correction has a title and description explaining the nature of the correction
- Use this endpoint to get evaluations and improvements for a hadis
- Evaluations may include updated translations, authenticity clarifications, or scholarly notes
- The `translation` field contains multilingual evaluations (typically JSON format)
- Each evaluation has a title and description explaining the nature of the evaluation
**Response Structure:** **Response Structure:**
- `hadis_id`: The ID of the hadis these corrections belong to
- `corrections_count`: Total number of corrections available
- `corrections`: Array of correction objects with details
- `hadis_id`: The ID of the hadis these evaluations belong to
- `corrections_count`: Total number of evaluations available
- `corrections`: Array of evaluation objects with details
**Note:** **Note:**
- If no corrections exist, the corrections array will be empty
- Corrections are ordered by creation date (newest first)
- Translation corrections may be in JSON format with language codes as keys
- If no evaluations exist, the corrections array will be empty
- Evaluations are ordered by creation date (newest first)
- Translation evaluations may be in JSON format with language codes as keys
""", """,
operation_summary="Get Hadis Corrections",
operation_summary="Get Hadis Evaluations",
operation_id="getHadisCorrections", operation_id="getHadisCorrections",
tags=['Dobodbi - Hadis'], tags=['Dobodbi - Hadis'],
manual_parameters=[ manual_parameters=[
@ -1029,7 +1029,7 @@ hadis_corrections_swagger = swagger_auto_schema(
], ],
responses={ responses={
status.HTTP_200_OK: openapi.Response( status.HTTP_200_OK: openapi.Response(
description="Successfully retrieved corrections for the specified hadis",
description="Successfully retrieved evaluations for the specified hadis",
examples={ examples={
"application/json": { "application/json": {
"hadis_id": 1800, "hadis_id": 1800,
@ -1037,7 +1037,7 @@ hadis_corrections_swagger = swagger_auto_schema(
"corrections": [ "corrections": [
{ {
"id": 1, "id": 1,
"title": "Translation Correction",
"title": "Translation Evaluation",
"slug":"достоинство-молитвы-и-ее-место-в-религии", "slug":"достоинство-молитвы-и-ее-место-в-религии",
"description": "Updated translation for better accuracy and clarity. The previous translation was slightly ambiguous in the context of intention and action.", "description": "Updated translation for better accuracy and clarity. The previous translation was slightly ambiguous in the context of intention and action.",
"translation":"Actions are judged by intentions, and every person will have what they intended", "translation":"Actions are judged by intentions, and every person will have what they intended",

4
apps/hadis/management/commands/seed_corrections.py

@ -44,8 +44,8 @@ class Command(BaseCommand):
for k in range(needed): for k in range(needed):
correction_num = current_count + k + 1 correction_num = current_count + k + 1
topics_en = ["Grammar Correction", "Context Clarification", "Alternative Translation", "Scholar Note"]
topics_ru = ["Исправление грамматики", "Уточнение контекста", "Альтернативный перевод", "Заметка ученого"]
topics_en = ["Grammar Evaluation", "Context Clarification", "Alternative Translation", "Scholar Note"]
topics_ru = ["Оценка грамматики", "Уточнение контекста", "Альтернативный перевод", "Заметка ученого"]
topic_idx = (correction_num - 1) % len(topics_en) topic_idx = (correction_num - 1) % len(topics_en)

6
apps/hadis/management/commands/seed_hadis_2.py

@ -99,9 +99,9 @@ class Command(BaseCommand):
# We'll assume these are translation corrections or scholarly notes # We'll assume these are translation corrections or scholarly notes
correction_title = ( correction_title = (
f"Correction for Hadis {hadis_id}",
f"اصلاحیه برای حدیث {hadis_id}",
f"Исправление для хадиса {hadis_id}"
f"Evaluation for Hadis {hadis_id}",
f"ارزیابی برای حدیث {hadis_id}",
f"Оценка для хадиса {hadis_id}"
) )
correction_desc = ( correction_desc = (

43
apps/hadis/migrations/0068_alter_correctionreference_options_and_more.py

@ -0,0 +1,43 @@
# Generated by Django 4.2.30 on 2026-10-28 09:44
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('hadis', '0067_populate_book_edition_books'),
]
operations = [
migrations.AlterModelOptions(
name='correctionreference',
options={'verbose_name': 'Evaluation Reference', 'verbose_name_plural': 'Evaluation References'},
),
migrations.AlterModelOptions(
name='correctionreferenceimage',
options={'verbose_name': 'Evaluation Reference Image', 'verbose_name_plural': 'Evaluation Reference Images'},
),
migrations.AlterModelOptions(
name='hadiscorrection',
options={'ordering': ('-created_at',), 'verbose_name': 'Hadis Evaluation', 'verbose_name_plural': 'Hadis Evaluations'},
),
migrations.AlterField(
model_name='hadiscorrection',
name='hadis',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hadis.hadis', verbose_name='hadis evaluation'),
),
migrations.AlterModelTable(
name='correctionreference',
table='hadis_evaluationreference',
),
migrations.AlterModelTable(
name='correctionreferenceimage',
table='hadis_evaluationreferenceimage',
),
migrations.AlterModelTable(
name='hadiscorrection',
table='hadis_hadisevaluation',
),
]

21
apps/hadis/models/hadis.py

@ -504,7 +504,7 @@ class ReferenceImage(models.Model):
super().save(*args, **kwargs) super().save(*args, **kwargs)
class HadisCorrection(models.Model): class HadisCorrection(models.Model):
hadis = models.ForeignKey(Hadis, verbose_name=_("hadis correction"), on_delete=models.CASCADE)
hadis = models.ForeignKey(Hadis, verbose_name=_("hadis evaluation"), on_delete=models.CASCADE)
title = models.JSONField(default = list , verbose_name=_('Title')) title = models.JSONField(default = list , verbose_name=_('Title'))
slug = models.SlugField(max_length=255, verbose_name=_('slug'), blank=True,unique=True, allow_unicode=True) slug = models.SlugField(max_length=255, verbose_name=_('slug'), blank=True,unique=True, allow_unicode=True)
legacy_id = models.CharField(max_length=255, unique=True, null=True, blank=True, db_index=True) legacy_id = models.CharField(max_length=255, unique=True, null=True, blank=True, db_index=True)
@ -521,8 +521,9 @@ class HadisCorrection(models.Model):
normalized_text = models.TextField(blank=True, null=True, verbose_name=_('normalized text for search')) normalized_text = models.TextField(blank=True, null=True, verbose_name=_('normalized text for search'))
class Meta: class Meta:
verbose_name = _("Hadis Correction")
verbose_name_plural = _("Hadis Corrections")
db_table = "hadis_hadisevaluation"
verbose_name = _("Hadis Evaluation")
verbose_name_plural = _("Hadis Evaluations")
ordering = ("-created_at",) ordering = ("-created_at",)
def __str__(self): def __str__(self):
@ -583,8 +584,8 @@ class HadisCorrection(models.Model):
@property @property
def share_link(self): def share_link(self):
if self.slug and self.hadis_id and self.hadis and self.hadis.slug: if self.slug and self.hadis_id and self.hadis and self.hadis.slug:
#https://dovodi.newhorizonco.uk/arguments/hadith/excellence-of-character-56?tab=text-corrections
return f"{settings.DOVODI_DOMAIN}/arguments/hadith/{self.hadis.slug}?tab=text-corrections"
#https://dovodi.newhorizonco.uk/arguments/hadith/excellence-of-character-56?tab=evaluations
return f"{settings.DOVODI_DOMAIN}/arguments/hadith/{self.hadis.slug}?tab=evaluations"
return None return None
def get_title(self, lang): def get_title(self, lang):
@ -693,11 +694,21 @@ class CorrectionReference(models.Model):
address = models.TextField(null=True, blank=True, verbose_name=_('Address')) # 👈 اضافه شده address = models.TextField(null=True, blank=True, verbose_name=_('Address')) # 👈 اضافه شده
url = models.URLField(max_length=1000, null=True, blank=True) # 👈 آپدیت طول به 1000 url = models.URLField(max_length=1000, null=True, blank=True) # 👈 آپدیت طول به 1000
class Meta:
db_table = "hadis_evaluationreference"
verbose_name = _("Evaluation Reference")
verbose_name_plural = _("Evaluation References")
class CorrectionReferenceImage(models.Model): class CorrectionReferenceImage(models.Model):
reference = models.ForeignKey(CorrectionReference, related_name='images', on_delete=models.CASCADE) reference = models.ForeignKey(CorrectionReference, related_name='images', on_delete=models.CASCADE)
image = models.ImageField(upload_to='hadis/correction_images/') image = models.ImageField(upload_to='hadis/correction_images/')
priority = models.IntegerField(default=0) priority = models.IntegerField(default=0)
class Meta:
db_table = "hadis_evaluationreferenceimage"
verbose_name = _("Evaluation Reference Image")
verbose_name_plural = _("Evaluation Reference Images")
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
from utils.watermark import apply_watermark_to_field_file from utils.watermark import apply_watermark_to_field_file
apply_watermark_to_field_file(self.image, position="bottom_left") apply_watermark_to_field_file(self.image, position="bottom_left")

22
apps/hadis/views/hadis.py

@ -897,7 +897,7 @@ class HadisCorrectionsView(ListAPIView):
class CategoryHadisCorrectionsView(ListAPIView): class CategoryHadisCorrectionsView(ListAPIView):
""" """
API view to retrieve all corrections across all hadiths belonging to a specific category
API view to retrieve all evaluations across all hadiths belonging to a specific category
""" """
serializer_class = HadisCorrectionSerializer serializer_class = HadisCorrectionSerializer
authentication_classes = [TokenAuthentication] authentication_classes = [TokenAuthentication]
@ -905,15 +905,15 @@ class CategoryHadisCorrectionsView(ListAPIView):
pagination_class = StandardResultsSetPagination pagination_class = StandardResultsSetPagination
@swagger_auto_schema( @swagger_auto_schema(
operation_summary="Get Category Hadis Corrections",
operation_description="Returns all text corrections across all hadiths belonging to a specific category, including hadis_info for each correction. Supports filtering by multiple hadiths and/or categories.",
operation_summary="Get Category Hadis Evaluations",
operation_description="Returns all evaluations across all hadiths belonging to a specific category, including hadis_info for each evaluation. Supports filtering by multiple hadiths and/or categories.",
tags=['Dobodbi - Hadis (V2)'], tags=['Dobodbi - Hadis (V2)'],
manual_parameters=[ manual_parameters=[
openapi.Parameter('search', openapi.IN_QUERY, description="Search in text or narrator", type=openapi.TYPE_STRING), openapi.Parameter('search', openapi.IN_QUERY, description="Search in text or narrator", type=openapi.TYPE_STRING),
openapi.Parameter('hadis_slug', openapi.IN_QUERY, description="Filter corrections by specific hadith slug (comma-separated for multiple)", type=openapi.TYPE_STRING),
openapi.Parameter('hadis_slugs', openapi.IN_QUERY, description="Filter corrections by multiple hadith slugs (comma-separated)", type=openapi.TYPE_STRING),
openapi.Parameter('category_slugs', openapi.IN_QUERY, description="Filter corrections by multiple category slugs (comma-separated)", type=openapi.TYPE_STRING),
openapi.Parameter('is_bookmark', openapi.IN_QUERY, description="Filter only bookmarked corrections (requires auth)", type=openapi.TYPE_BOOLEAN),
openapi.Parameter('hadis_slug', openapi.IN_QUERY, description="Filter evaluations by specific hadith slug (comma-separated for multiple)", type=openapi.TYPE_STRING),
openapi.Parameter('hadis_slugs', openapi.IN_QUERY, description="Filter evaluations by multiple hadith slugs (comma-separated)", type=openapi.TYPE_STRING),
openapi.Parameter('category_slugs', openapi.IN_QUERY, description="Filter evaluations by multiple category slugs (comma-separated)", type=openapi.TYPE_STRING),
openapi.Parameter('is_bookmark', openapi.IN_QUERY, description="Filter only bookmarked evaluations (requires auth)", type=openapi.TYPE_BOOLEAN),
] ]
) )
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -1357,15 +1357,15 @@ from ..serializers.hadis import HadisCorrectionDetailSerializer, HadisInterpreta
from ..models import HadisInterpretation from ..models import HadisInterpretation
class HadisCorrectionDetailView(RetrieveAPIView): class HadisCorrectionDetailView(RetrieveAPIView):
"""API View to get full details of a specific HadisCorrection by slug"""
"""API View to get full details of a specific HadisCorrection (Evaluation) by slug"""
serializer_class = HadisCorrectionDetailSerializer serializer_class = HadisCorrectionDetailSerializer
lookup_field = 'slug' lookup_field = 'slug'
lookup_url_kwarg = 'correction_slug' lookup_url_kwarg = 'correction_slug'
permission_classes = [AllowAny] permission_classes = [AllowAny]
@swagger_auto_schema( @swagger_auto_schema(
operation_summary="Get Hadis Correction Detail",
operation_description="Returns the full details of a specific hadis correction, including text, translations, and its book references.",
operation_summary="Get Hadis Evaluation Detail",
operation_description="Returns the full details of a specific hadis evaluation, including text, translations, and its book references.",
tags=['Dobodbi - Hadis (V2)'], tags=['Dobodbi - Hadis (V2)'],
) )
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -1391,7 +1391,7 @@ class HadisCorrectionDetailView(RetrieveAPIView):
obj = queryset.filter(id=int(self.kwargs[lookup_url_kwarg])).first() obj = queryset.filter(id=int(self.kwargs[lookup_url_kwarg])).first()
if not obj: if not obj:
raise Http404("No HadisCorrection matches the given query.")
raise Http404("No Hadis Evaluation matches the given query.")
self.check_object_permissions(self.request, obj) self.check_object_permissions(self.request, obj)
return obj return obj

Loading…
Cancel
Save