import json from django.contrib import admin from django.db import models from django.utils.translation import gettext_lazy as _ from django.utils.safestring import mark_safe from django.utils.html import format_html from dj_language.models import Language from django import forms from import_export import fields, widgets, resources from import_export.admin import ImportExportModelAdmin from unfold.decorators import display from unfold.admin import ModelAdmin, TabularInline from unfold.forms import AdminPasswordChangeForm, UserChangeForm, UserCreationForm from unfold.contrib.filters.admin import ( RangeDateFilter, RangeNumericFilter, SingleNumericFilter, ChoicesDropdownFilter ) from apps.dobodbi_calendar.models import CalendarOccasions from utils.json_editor_field import JsonEditorWidget from utils.admin import project_admin_site from utils.schema import get_calender_dates_schema class CalendarOccasionsForm(forms.ModelForm): class Meta: model = CalendarOccasions fields = '__all__' widgets = { 'dates': JsonEditorWidget(attrs={ 'schema': get_calender_dates_schema(), 'title': _('Dates'), }), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) class CalendarOccasionsAdmin(ModelAdmin): form = CalendarOccasionsForm ordering = ('-id',) list_display = [ "title", "display_occasion_type", "display_event_type", "is_global", "is_yearly", "display_dates", ] list_filter = [ ("occasion_type", ChoicesDropdownFilter), ("event_type", ChoicesDropdownFilter), "is_global", "is_yearly", ("created_at", RangeDateFilter), ] search_fields = [ "title", "dates", ] fieldsets = ( ("Basic Information", { "fields": ( "title", "is_global", "is_yearly", "occasion_type", "event_type", ), "description": "Main information about the calendar occasion", }), ("Dates Configuration", { "fields": ("dates",), "classes": ("collapse",), "description": "Configure dates for this occasion", }), ("Metadata", { "fields": ("created_at", "updated_at"), "classes": ("collapse",), "description": "Metadata information", }), ) readonly_fields = ["created_at", "updated_at"] # سفارشی‌سازی اکشن‌ها actions = ["make_global", "make_not_global"] # متدهای اکشن @admin.action(description="Mark selected occasions as global") def make_global(self, request, queryset): queryset.update(is_global=True) @admin.action(description="Mark selected occasions as not global") def make_not_global(self, request, queryset): queryset.update(is_global=False) @display(description="Occasion Type", label=True) def display_occasion_type(self, obj): return obj.get_occasion_type_display() @display(description="Event Type", label=True) def display_event_type(self, obj): return obj.get_event_type_display() @display(description="Dates") def display_dates(self, obj): from django.utils.html import format_html return "\n".join([f"{i['month']}/{i['day']}" for i in obj.dates]) def get_search_results(self, request, queryset, search_term): queryset, use_distinct = super().get_search_results(request, queryset, search_term) try: # امکان جستجو در فیلد JSON import json json.loads(search_term) queryset |= self.model.objects.filter(dates__contains=search_term) except ValueError: pass return queryset, use_distinct project_admin_site.register(CalendarOccasions, CalendarOccasionsAdmin)