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 unfold.widgets import UnfoldAdminTextInputWidget, UnfoldAdminTextareaWidget, UnfoldAdminExpandableTextareaWidget from utils.multilang_json_widget import MultiLanguageJSONWidget import json from utils.admin import dovoodi_admin_site 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') # Custom Forms for JSON Fields class TransmittersAdminForm(forms.ModelForm): """Custom form for Transmitters with JSON editor widgets""" class Meta: model = Transmitters fields = '__all__' widgets = { 'full_name': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'kunya': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'known_as': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'nickname': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'origin': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'lived_in': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'died_in': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'description': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextareaWidget), } # Custom Forms for JSON Fields class NarratorLayerAdminForm(forms.ModelForm): """Custom form for NarratorLayer with JSON editor widgets""" class Meta: model = NarratorLayer fields = '__all__' widgets = { 'name': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'description': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextareaWidget), } class TransmitterReliabilityAdminForm(forms.ModelForm): """Custom form for TransmitterReliability with JSON editor widgets""" class Meta: model = TransmitterReliability fields = '__all__' widgets = { 'title': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), } class OpinionStatusAdminForm(forms.ModelForm): """Custom form for OpinionStatus with JSON editor widgets""" class Meta: model = OpinionStatus fields = '__all__' widgets = { 'title': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), } class TransmitterOpinionAdminForm(forms.ModelForm): """Custom form for TransmitterOpinion with JSON editor widgets""" class Meta: model = TransmitterOpinion fields = '__all__' widgets = { 'scholar_name': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'opinion_text': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextareaWidget), } class TransmitterOriginalTextAdminForm(forms.ModelForm): """Custom form for TransmitterOriginalText with JSON editor widgets""" class Meta: model = TransmitterOriginalText fields = '__all__' widgets = { 'title': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextInputWidget), 'text': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextareaWidget), 'translation': MultiLanguageJSONWidget(input_widget_class=UnfoldAdminTextareaWidget), } class TransmitterOpinionInline(TabularInline): """Inline for TransmitterOpinion in Transmitters admin""" model = TransmitterOpinion form = TransmitterOpinionAdminForm extra = 0 fields = ('scholar_name', 'opinion_text', 'status') def has_add_permission(self, request, obj=None): return False class TransmitterOriginalTextInline(TabularInline): """Inline for TransmitterOriginalText in Transmitters admin""" model = TransmitterOriginalText form = TransmitterOriginalTextAdminForm extra = 0 fields = ('title', 'text', 'translation', 'slug') def has_add_permission(self, request, obj=None): return False class TransmittersAdmin(ModelAdmin): """Admin for Transmitters model""" form = TransmittersAdminForm list_display = ('display_header', 'birth_year_hijri', 'death_year_hijri') list_filter = ('birth_year_hijri', 'death_year_hijri') search_fields = ('full_name', 'description') readonly_fields = ('created_at', 'updated_at') inlines = [HadisTransmitterInline, TransmitterOpinionInline, TransmitterOriginalTextInline] fieldsets = ( (None, { 'fields': ('full_name', 'birth_year_hijri', 'death_year_hijri','known_as','nickname') }), (_('Additional Information'), { 'fields': ('description','origin','lived_in','died_in','kunya'), # 'classes': ('collapse',) }), (_('Timestamps'), { 'fields': ('created_at', 'updated_at'), # 'classes': ('collapse',) }), ) @display(description=_('Full Name'), ordering='full_name') def get_full_name_display(self, obj): """ Parses the JSON full_name and returns the first item's title. """ if obj.full_name and isinstance(obj.full_name, list) and len(obj.full_name) > 0: # Safely get the first item first_item = obj.full_name[0] if isinstance(first_item, dict): return first_item.get('title', '-') return '-' @display(description=_("Transmitter"), header=True) def display_header(self, obj): return self.get_full_name_display(obj), class HadisTransmitterAdmin(ModelAdmin): """Admin for HadisTransmitter model""" list_display = ('hadis', 'transmitter', 'order', 'created_at') list_filter = ( 'created_at',) search_fields = ('hadis__title', 'transmitter__full_name') readonly_fields = ('created_at',) ordering = ('hadis', 'order') fieldsets = ( (None, { 'fields': ('hadis', 'transmitter', 'order') }), (_('Timestamps'), { 'fields': ('created_at',), 'classes': ('collapse',) }), ) # Main Admin Classes class NarratorLayerAdmin(ModelAdmin): """Admin for NarratorLayer model""" form = NarratorLayerAdminForm list_display = ('number', 'get_name_display', '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',) }), ) @display(description=_('Name'), ordering='name') def get_name_display(self, obj): return self._extract_first_text(obj.name) def _extract_first_text(self, json_data): """Helper to safely extract the first 'title' from a JSON list""" if json_data and isinstance(json_data, list) and len(json_data) > 0: first_item = json_data[0] if isinstance(first_item, dict): return first_item.get('title', '-') return '-' class TransmitterReliabilityAdmin(ModelAdmin): """Admin for TransmitterReliability model""" form = TransmitterReliabilityAdminForm list_display = ('get_title_display', 'slug', 'color') list_filter = ('color',) search_fields = ('title', 'slug') readonly_fields = ('slug',) fieldsets = ( (None, { 'fields': ('title', 'slug', 'color') }), ) @display(description=_('Title'), ordering='title') def get_title_display(self, obj): return self._extract_first_text(obj.title) def _extract_first_text(self, json_data): """Helper to safely extract the first 'title' from a JSON list""" if json_data and isinstance(json_data, list) and len(json_data) > 0: first_item = json_data[0] if isinstance(first_item, dict): return first_item.get('title', '-') return '-' class OpinionStatusAdmin(ModelAdmin): """Admin for OpinionStatus model""" form = OpinionStatusAdminForm list_display = ('get_title_display', 'slug', 'color') list_filter = ('color',) search_fields = ('title', 'slug') readonly_fields = ('slug',) fieldsets = ( (None, { 'fields': ('title', 'slug', 'color') }), ) @display(description=_('Title'), ordering='title') def get_title_display(self, obj): return self._extract_first_text(obj.title) def _extract_first_text(self, json_data): """Helper to safely extract the first 'title' from a JSON list""" if json_data and isinstance(json_data, list) and len(json_data) > 0: first_item = json_data[0] if isinstance(first_item, dict): return first_item.get('title', '-') return '-' class TransmitterOpinionAdmin(ModelAdmin): """Admin for TransmitterOpinion model""" form = TransmitterOpinionAdminForm list_display = ('transmitter', 'get_scholar_name_display', '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',) }), ) @display(description=_('Scholar Name'), ordering='scholar_name') def get_scholar_name_display(self, obj): return self._extract_first_text(obj.scholar_name) def _extract_first_text(self, json_data): """Helper to safely extract the first 'title' from a JSON list""" if json_data and isinstance(json_data, list) and len(json_data) > 0: first_item = json_data[0] if isinstance(first_item, dict): return first_item.get('title', '-') return '-' class TransmitterOriginalTextAdmin(ModelAdmin): """Admin for TransmitterOriginalText model""" form = TransmitterOriginalTextAdminForm list_display = ('transmitter', 'get_title_display', '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',) }), ) @display(description=_('Title'), ordering='title') def get_title_display(self, obj): return self._extract_first_text(obj.title) def _extract_first_text(self, json_data): """Helper to safely extract the first 'title' from a JSON list""" if json_data and isinstance(json_data, list) and len(json_data) > 0: first_item = json_data[0] if isinstance(first_item, dict): return first_item.get('title', '-') return '-' # Register models with the custom admin site dovoodi_admin_site.register(Transmitters, TransmittersAdmin) dovoodi_admin_site.register(HadisTransmitter, HadisTransmitterAdmin) dovoodi_admin_site.register(NarratorLayer, NarratorLayerAdmin) dovoodi_admin_site.register(TransmitterReliability, TransmitterReliabilityAdmin) dovoodi_admin_site.register(OpinionStatus, OpinionStatusAdmin) dovoodi_admin_site.register(TransmitterOpinion, TransmitterOpinionAdmin) dovoodi_admin_site.register(TransmitterOriginalText, TransmitterOriginalTextAdmin)