diff --git a/apps/hadis/admin/hadis.py b/apps/hadis/admin/hadis.py index ef25376..5cecd33 100644 --- a/apps/hadis/admin/hadis.py +++ b/apps/hadis/admin/hadis.py @@ -10,7 +10,7 @@ import json from utils.admin import project_admin_site from ..models import ( Hadis, HadisReference, HadisTag, HadisStatus, ReferenceImage, - HadisCollection, HadisInCollection + HadisCollection, HadisInCollection, HadisCorrection ) @@ -230,10 +230,160 @@ class HadisCollectionAdmin(ModelAdmin): ) +class HadisInCollectionAdmin(ModelAdmin): + """Admin for HadisInCollection model""" + list_display = ('hadis', 'collection', 'order', 'created_at') + list_filter = ('collection', 'created_at') + search_fields = ('hadis__title', 'collection__title') + readonly_fields = ('created_at',) + ordering = ('collection', 'order') + + fieldsets = ( + (None, { + 'fields': ('hadis', 'collection', 'order') + }), + (_('Timestamps'), { + 'fields': ('created_at',), + 'classes': ('collapse',) + }), + ) + + +class HadisCorrectionAdminForm(forms.ModelForm): + """Custom form for HadisCorrection with JSON editor widgets""" + + class Meta: + model = HadisCorrection + fields = '__all__' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Schema for title JSON field + title_schema = { + "type": "array", + "title": "Titles", + "items": { + "type": "object", + "title": "Title", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Title Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Schema for description JSON field + description_schema = { + "type": "array", + "title": "Descriptions", + "items": { + "type": "object", + "title": "Description", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Description Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Schema for translation JSON field + translation_schema = { + "type": "array", + "title": "Translations", + "items": { + "type": "object", + "title": "Translation", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Translation Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Apply JSON editor widgets + self.fields['title'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(title_schema), + 'title': 'Titles' + }) + + self.fields['description'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(description_schema), + 'title': 'Descriptions' + }) + + self.fields['translation'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(translation_schema), + 'title': 'Translations' + }) + + +class HadisCorrectionAdmin(ModelAdmin): + """Admin for HadisCorrection model""" + form = HadisCorrectionAdminForm + list_display = ('hadis', 'title', 'slug', 'created_at') + list_filter = ('created_at', 'hadis__category') + search_fields = ('hadis__title', 'title', 'slug') + readonly_fields = ('slug', 'created_at', 'updated_at', 'share_link') + ordering = ('-created_at',) + + fieldsets = ( + (None, { + 'fields': ('hadis', 'title', 'slug') + }), + (_('Content'), { + 'fields': ('description', 'translation') + }), + (_('Additional Information'), { + 'fields': ('share_link',), + 'classes': ('collapse',) + }), + (_('Timestamps'), { + 'fields': ('created_at', 'updated_at'), + 'classes': ('collapse',) + }), + ) + + # Register models with the custom admin site project_admin_site.register(HadisTag, HadisTagAdmin) project_admin_site.register(HadisStatus, HadisStatusAdmin) project_admin_site.register(Hadis, HadisAdmin) project_admin_site.register(HadisReference, HadisReferenceAdmin) project_admin_site.register(ReferenceImage, ReferenceImageAdmin) -project_admin_site.register(HadisCollection, HadisCollectionAdmin) \ No newline at end of file +project_admin_site.register(HadisCollection, HadisCollectionAdmin) +project_admin_site.register(HadisInCollection, HadisInCollectionAdmin) +project_admin_site.register(HadisCorrection, HadisCorrectionAdmin) \ No newline at end of file diff --git a/apps/hadis/admin/transmitter.py b/apps/hadis/admin/transmitter.py index 5f6775f..0872d6e 100644 --- a/apps/hadis/admin/transmitter.py +++ b/apps/hadis/admin/transmitter.py @@ -1,18 +1,37 @@ from django.contrib import admin +from django import forms from django.utils.translation import gettext_lazy as _ from unfold.admin import ModelAdmin, TabularInline from unfold.decorators import display, action +from unfold.contrib.forms.widgets import WysiwygWidget +from utils.json_editor_field import JsonEditorWidget +import json from utils.admin import project_admin_site -from ..models import Transmitters, HadisTransmitter - +from ..models import ( + Transmitters, HadisTransmitter, NarratorLayer, TransmitterReliability, + OpinionStatus, TransmitterOpinion, TransmitterOriginalText +) class HadisTransmitterInline(TabularInline): """Inline for HadisTransmitter in Transmitters admin""" model = HadisTransmitter extra = 0 fields = ('hadis', 'order') - readonly_fields = ('created_at',) + + +class TransmitterOpinionInline(TabularInline): + """Inline for TransmitterOpinion in Transmitters admin""" + model = TransmitterOpinion + extra = 0 + fields = ('scholar_name', 'status') + + +class TransmitterOriginalTextInline(TabularInline): + """Inline for TransmitterOriginalText in Transmitters admin""" + model = TransmitterOriginalText + extra = 0 + fields = ('title', 'slug') class TransmittersAdmin(ModelAdmin): @@ -21,7 +40,7 @@ class TransmittersAdmin(ModelAdmin): list_filter = ('birth_year_hijri', 'death_year_hijri') search_fields = ('full_name', 'description') readonly_fields = ('created_at', 'updated_at') - inlines = [HadisTransmitterInline] + inlines = [HadisTransmitterInline, TransmitterOpinionInline, TransmitterOriginalTextInline] fieldsets = ( (None, { @@ -68,6 +87,445 @@ class HadisTransmitterAdmin(ModelAdmin): ) +# Custom Forms for JSON Fields +class NarratorLayerAdminForm(forms.ModelForm): + """Custom form for NarratorLayer with JSON editor widgets""" + + class Meta: + model = NarratorLayer + fields = '__all__' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Schema for name JSON field + name_schema = { + "type": "array", + "title": "Names", + "items": { + "type": "object", + "title": "Name", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Name Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Schema for description JSON field + description_schema = { + "type": "array", + "title": "Descriptions", + "items": { + "type": "object", + "title": "Description", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Description Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Apply JSON editor widgets + self.fields['name'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(name_schema), + 'title': 'Names' + }) + + self.fields['description'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(description_schema), + 'title': 'Descriptions' + }) + + +class TransmitterReliabilityAdminForm(forms.ModelForm): + """Custom form for TransmitterReliability with JSON editor widgets""" + + class Meta: + model = TransmitterReliability + fields = '__all__' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Schema for title JSON field + title_schema = { + "type": "array", + "title": "Titles", + "items": { + "type": "object", + "title": "Title", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Title Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Apply JSON editor widgets + self.fields['title'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(title_schema), + 'title': 'Titles' + }) + + +class OpinionStatusAdminForm(forms.ModelForm): + """Custom form for OpinionStatus with JSON editor widgets""" + + class Meta: + model = OpinionStatus + fields = '__all__' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Schema for title JSON field + title_schema = { + "type": "array", + "title": "Titles", + "items": { + "type": "object", + "title": "Title", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Title Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Apply JSON editor widgets + self.fields['title'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(title_schema), + 'title': 'Titles' + }) + + +class TransmitterOpinionAdminForm(forms.ModelForm): + """Custom form for TransmitterOpinion with JSON editor widgets""" + + class Meta: + model = TransmitterOpinion + fields = '__all__' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Schema for scholar_name JSON field + scholar_name_schema = { + "type": "array", + "title": "Scholar Names", + "items": { + "type": "object", + "title": "Scholar Name", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Scholar Name Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Schema for opinion_text JSON field + opinion_text_schema = { + "type": "array", + "title": "Opinion Texts", + "items": { + "type": "object", + "title": "Opinion Text", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Opinion Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Apply JSON editor widgets + self.fields['scholar_name'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(scholar_name_schema), + 'title': 'Scholar Names' + }) + + self.fields['opinion_text'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(opinion_text_schema), + 'title': 'Opinion Texts' + }) + + +class TransmitterOriginalTextAdminForm(forms.ModelForm): + """Custom form for TransmitterOriginalText with JSON editor widgets""" + + class Meta: + model = TransmitterOriginalText + fields = '__all__' + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Schema for title JSON field + title_schema = { + "type": "array", + "title": "Titles", + "items": { + "type": "object", + "title": "Title", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Title Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Schema for text JSON field + text_schema = { + "type": "array", + "title": "Texts", + "items": { + "type": "object", + "title": "Text", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Text Content" + } + }, + "required": ["language_code", "text"] + } + } + + # Schema for translation JSON field + translation_schema = { + "type": "array", + "title": "Translations", + "items": { + "type": "object", + "title": "Translation", + "properties": { + "language_code": { + "type": "string", + "title": "Language Code", + "enum": ["en", "fa", "ar", "ur", "ru"], + "options": { + "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] + } + }, + "text": { + "type": "string", + "title": "Translation Text" + } + }, + "required": ["language_code", "text"] + } + } + + # Apply JSON editor widgets + self.fields['title'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(title_schema), + 'title': 'Titles' + }) + + self.fields['text'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(text_schema), + 'title': 'Texts' + }) + + self.fields['translation'].widget = JsonEditorWidget(attrs={ + 'schema': json.dumps(translation_schema), + 'title': 'Translations' + }) + + +# Main Admin Classes +class NarratorLayerAdmin(ModelAdmin): + """Admin for NarratorLayer model""" + form = NarratorLayerAdminForm + list_display = ('number', 'name', 'slug', 'created_at') + list_filter = ('created_at', 'updated_at') + search_fields = ('name', 'slug') + readonly_fields = ('slug', 'created_at', 'updated_at') + ordering = ('number',) + + fieldsets = ( + (None, { + 'fields': ('number', 'name', 'slug') + }), + (_('Content'), { + 'fields': ('description',) + }), + (_('Timestamps'), { + 'fields': ('created_at', 'updated_at'), + 'classes': ('collapse',) + }), + ) + + +class TransmitterReliabilityAdmin(ModelAdmin): + """Admin for TransmitterReliability model""" + form = TransmitterReliabilityAdminForm + list_display = ('title', 'slug', 'color') + list_filter = ('color',) + search_fields = ('title', 'slug') + readonly_fields = ('slug',) + + fieldsets = ( + (None, { + 'fields': ('title', 'slug', 'color') + }), + ) + + +class OpinionStatusAdmin(ModelAdmin): + """Admin for OpinionStatus model""" + form = OpinionStatusAdminForm + list_display = ('title', 'slug', 'color') + list_filter = ('color',) + search_fields = ('title', 'slug') + readonly_fields = ('slug',) + + fieldsets = ( + (None, { + 'fields': ('title', 'slug', 'color') + }), + ) + + + + +class TransmitterOpinionAdmin(ModelAdmin): + """Admin for TransmitterOpinion model""" + form = TransmitterOpinionAdminForm + list_display = ('transmitter', 'scholar_name', 'status', 'created_at') + list_filter = ('status', 'created_at', 'transmitter') + search_fields = ('transmitter__full_name', 'scholar_name') + readonly_fields = ('created_at', 'updated_at') + + fieldsets = ( + (None, { + 'fields': ('transmitter', 'scholar_name') + }), + (_('Content'), { + 'fields': ('opinion_text', 'status') + }), + (_('Timestamps'), { + 'fields': ('created_at', 'updated_at'), + 'classes': ('collapse',) + }), + ) + + + + + +class TransmitterOriginalTextAdmin(ModelAdmin): + """Admin for TransmitterOriginalText model""" + form = TransmitterOriginalTextAdminForm + list_display = ('transmitter', 'title', 'slug') + list_filter = ('transmitter',) + search_fields = ('transmitter__full_name', 'title', 'slug') + readonly_fields = ('slug',) + + fieldsets = ( + (None, { + 'fields': ('transmitter', 'title', 'slug') + }), + (_('Content'), { + 'fields': ('text', 'translation') + }), + (_('Additional Information'), { + 'fields': ('share_link',), + 'classes': ('collapse',) + }), + ) + + # Register models with the custom admin site project_admin_site.register(Transmitters, TransmittersAdmin) -project_admin_site.register(HadisTransmitter, HadisTransmitterAdmin) \ No newline at end of file +project_admin_site.register(HadisTransmitter, HadisTransmitterAdmin) +project_admin_site.register(NarratorLayer, NarratorLayerAdmin) +project_admin_site.register(TransmitterReliability, TransmitterReliabilityAdmin) +project_admin_site.register(OpinionStatus, OpinionStatusAdmin) +project_admin_site.register(TransmitterOpinion, TransmitterOpinionAdmin) +project_admin_site.register(TransmitterOriginalText, TransmitterOriginalTextAdmin) \ No newline at end of file diff --git a/apps/hadis/models/transmitter.py b/apps/hadis/models/transmitter.py index 1b7fa14..a849fb2 100644 --- a/apps/hadis/models/transmitter.py +++ b/apps/hadis/models/transmitter.py @@ -114,8 +114,8 @@ class TransmitterReliability(models.Model): return None class Meta: - verbose_name = _('transmitter reliability') - verbose_name_plural = _('transmitter reliability') + verbose_name = _('Transmitter Reliability') + verbose_name_plural = _('Transmitter Reliabilities') @@ -369,8 +369,8 @@ class OpinionStatus(models.Model): return None class Meta: - verbose_name = _('transmitter reliability') - verbose_name_plural = _('transmitter reliability') + verbose_name = _('Opinion Status') + verbose_name_plural = _('Opinion Statuses') class TransmitterOpinion(models.Model):