from django import forms from django.contrib import admin from django.utils.translation import gettext_lazy as _ from unfold.admin import ModelAdmin, TabularInline from unfold.contrib.forms.widgets import WysiwygWidget from unfold.decorators import display, action from utils.json_editor_field import JsonEditorWidget import json from utils.admin import dovoodi_admin_site,dovoodi_admin_site from ..models import ( Hadis, HadisReference, HadisTag, HadisStatus, ReferenceImage, HadisCollection, HadisInCollection, HadisCorrection ) # Custom Forms for JSON Fields class HadisAdminForm(forms.ModelForm): """Custom form for Hadis with JSON editor widgets""" class Meta: model = Hadis fields = '__all__' widgets = { 'explanation': WysiwygWidget(), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 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"], "options": { "enum_titles": ["English", "Persian", "Arabic", "Urdu"] } }, "text": { # <‑‑ use text, not title "type": "string", "title": "Translation Text" } }, "required": ["language_code", "text"] # <‑‑ update required key } } # Schema for links JSON field (array of objects with title and link) links_schema = { "type": "array", "title": "Links", "items": { "type": "object", "title": "Link", "properties": { "title": { "type": "string", "title": "Link Title" }, "link": { "type": "string", "title": "URL", "format": "uri" } }, "required": ["title", "link"] } } # Schema for explanations JSON field (array of objects with title and description) explanations_schema = { "type": "array", "title": "Explanations", "items": { "type": "object", "title": "Explanation", "properties": { "language_code": { "type": "string", "title": "Language Code", "enum": ["en", "fa", "ar", "ur", "ru"], "options": { "enum_titles": ["English", "Persian", "Arabic", "Urdu", "Russian"] } }, "title": { "type": "string", "title": "Title" }, "description": { "type": "string", "title": "Description" } }, "required": ["language_code", "title", "description"] } } # Schema for address_details JSON field (array of objects with text and priority) address_details_schema = { "type": "array", "title": "Address Details", "items": { "type": "object", "title": "Address Detail", "properties": { "text": { "type": "string", "title": "Address Text" }, "priority": { "type": "integer", "title": "Priority", "minimum": 0 } }, "required": ["text", "priority"] } } # Apply JSON editor widgets self.fields['translation'].widget = JsonEditorWidget(attrs={ 'schema': json.dumps(translation_schema), 'title': 'Translations' }) self.fields['links'].widget = JsonEditorWidget(attrs={ 'schema': json.dumps(links_schema), 'title': 'Links' }) self.fields['explanations'].widget = JsonEditorWidget(attrs={ 'schema': json.dumps(explanations_schema), 'title': 'Explanations' }) self.fields['address_details'].widget = JsonEditorWidget(attrs={ 'schema': json.dumps(address_details_schema), 'title': 'Address Details' }) # Inline Admin Classes class ReferenceImageInline(TabularInline): """Inline for ReferenceImage in HadisReference admin""" model = ReferenceImage extra = 0 fields = ('thumbnail', 'priority') ordering = ('priority',) class HadisReferenceInline(TabularInline): """Inline for HadisReference in Hadis admin""" model = HadisReference extra = 0 fields = ('book_reference',) readonly_fields = ('created_at',) # Main Admin Classes class HadisTagAdmin(ModelAdmin): """Admin for HadisTag model""" list_display = ('title', 'status', 'created_at') list_filter = ('status', 'created_at') search_fields = ('title',) readonly_fields = ('created_at', 'updated_at') fieldsets = ( (None, { 'fields': ('title', 'status') }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) class HadisStatusAdmin(ModelAdmin): """Admin for HadisStatus model""" list_display = ('title', 'color', 'order') list_filter = ('color',) search_fields = ('title',) ordering = ('order',) fieldsets = ( (None, { 'fields': ('title', 'color', 'order') }), ) class HadisAdmin(ModelAdmin): """Admin for Hadis model""" form = HadisAdminForm list_display = ('number', 'title', 'category', 'status', 'hadis_status', 'created_at') list_filter = ('status', 'hadis_status', 'category', 'created_at') search_fields = ('title', 'text', 'category__title') readonly_fields = ('created_at', 'updated_at', 'share_link') ordering = ('category', 'number') inlines = [HadisReferenceInline] filter_horizontal = ('tags',) fieldsets = ( (None, { 'fields': ('category', 'number', 'title', 'status') }), (_('Content'), { 'fields': ('text', 'translation', 'explanation', 'explanations') }), (_('Status & Classification'), { 'fields': ('hadis_status', 'hadis_status_text', 'tags') }), (_('Additional Information'), { 'fields': ('address', 'address_details', 'links', 'share_link'), 'classes': ('collapse',) }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) class HadisReferenceAdmin(ModelAdmin): """Admin for HadisReference model""" list_display = ('hadis', 'book_reference', 'created_at') list_filter = ('created_at', 'book_reference') search_fields = ('hadis__title', 'book_reference__title') readonly_fields = ('created_at',) inlines = [ReferenceImageInline] fieldsets = ( (None, { 'fields': ('hadis', 'book_reference') }), (_('Timestamps'), { 'fields': ('created_at',), 'classes': ('collapse',) }), ) class ReferenceImageAdmin(ModelAdmin): """Admin for ReferenceImage model""" list_display = ('reference', 'thumbnail', 'priority') list_filter = ('priority',) search_fields = ('reference__hadis__title', 'reference__book__title') ordering = ('reference', 'priority') fieldsets = ( (None, { 'fields': ('reference', 'thumbnail', 'priority') }), ) class HadisInCollectionInline(TabularInline): """Inline for HadisInCollection in HadisCollection admin""" model = HadisInCollection extra = 0 fields = ('hadis', 'order') ordering = ('order',) class HadisCollectionAdmin(ModelAdmin): """Admin for HadisCollection model""" list_display = ('title', 'slug', 'status', 'order', 'created_at') list_filter = ('status', 'created_at') search_fields = ('title', 'slug', 'summary') readonly_fields = ('slug', 'created_at', 'updated_at') ordering = ('order',) inlines = [HadisInCollectionInline] fieldsets = ( (None, { 'fields': ('title', 'slug', 'summary', 'status', 'order', 'thumbnail') }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), 'classes': ('collapse',) }), ) 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 dovoodi admin site dovoodi_admin_site.register(HadisTag, HadisTagAdmin) dovoodi_admin_site.register(HadisStatus, HadisStatusAdmin) dovoodi_admin_site.register(Hadis, HadisAdmin) dovoodi_admin_site.register(HadisReference, HadisReferenceAdmin) dovoodi_admin_site.register(ReferenceImage, ReferenceImageAdmin) dovoodi_admin_site.register(HadisCollection, HadisCollectionAdmin) dovoodi_admin_site.register(HadisInCollection, HadisInCollectionAdmin) dovoodi_admin_site.register(HadisCorrection, HadisCorrectionAdmin)