You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
7.5 KiB
218 lines
7.5 KiB
import json
|
|
from django.contrib import admin
|
|
from django.db import models
|
|
from django.http import JsonResponse
|
|
from django.shortcuts import get_object_or_404
|
|
from django.urls import path
|
|
from django.utils.dateformat import format as date_format
|
|
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 dovoodi_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
|
|
change_list_template = "admin/dobodbi_calendar/calendar_event_list.html"
|
|
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_urls(self):
|
|
urls = super().get_urls()
|
|
custom_urls = [
|
|
path(
|
|
"manage/create/",
|
|
self.admin_site.admin_view(self.create_event_view),
|
|
name="dobodbi_calendar_calendaroccasions_create",
|
|
),
|
|
path(
|
|
"manage/<int:event_id>/update/",
|
|
self.admin_site.admin_view(self.update_event_view),
|
|
name="dobodbi_calendar_calendaroccasions_update",
|
|
),
|
|
]
|
|
return custom_urls + urls
|
|
|
|
def changelist_view(self, request, extra_context=None):
|
|
events = CalendarOccasions.objects.all().order_by("-updated_at", "-id")
|
|
event_rows = [
|
|
{
|
|
"id": event.id,
|
|
"title": event.title,
|
|
"occasion_type": event.occasion_type,
|
|
"occasion_type_label": event.get_occasion_type_display(),
|
|
"event_type": event.event_type or "",
|
|
"event_type_label": event.get_event_type_display() if event.event_type else "-",
|
|
"is_global": event.is_global,
|
|
"is_yearly": event.is_yearly,
|
|
"dates": event.dates or [],
|
|
"dates_preview": ", ".join(
|
|
[
|
|
f"{date_item.get('year', '')}/{date_item.get('month', '')}/{date_item.get('day', '')}".strip("/")
|
|
for date_item in (event.dates or [])
|
|
]
|
|
),
|
|
"updated_at": date_format(event.updated_at, "Y-m-d H:i"),
|
|
"created_at": date_format(event.created_at, "Y-m-d H:i"),
|
|
}
|
|
for event in events
|
|
]
|
|
|
|
extra_context = extra_context or {}
|
|
extra_context.update(
|
|
{
|
|
"calendar_events": event_rows,
|
|
"calendar_event_type_choices": [
|
|
{"value": value, "label": label}
|
|
for value, label in CalendarOccasions.EventType.choices
|
|
],
|
|
"calendar_occasion_type_choices": [
|
|
{"value": value, "label": label}
|
|
for value, label in CalendarOccasions.OccasionType.choices
|
|
],
|
|
}
|
|
)
|
|
return super().changelist_view(request, extra_context=extra_context)
|
|
|
|
def create_event_view(self, request):
|
|
if request.method != "POST":
|
|
return JsonResponse({"ok": False, "error": "Method not allowed."}, status=405)
|
|
|
|
form = CalendarOccasionsForm(request.POST)
|
|
if form.is_valid():
|
|
event = form.save()
|
|
return JsonResponse({"ok": True, "id": event.id})
|
|
return JsonResponse({"ok": False, "errors": form.errors.get_json_data()}, status=400)
|
|
|
|
def update_event_view(self, request, event_id):
|
|
if request.method != "POST":
|
|
return JsonResponse({"ok": False, "error": "Method not allowed."}, status=405)
|
|
|
|
event = get_object_or_404(CalendarOccasions, pk=event_id)
|
|
form = CalendarOccasionsForm(request.POST, instance=event)
|
|
if form.is_valid():
|
|
form.save()
|
|
return JsonResponse({"ok": True, "id": event.id})
|
|
return JsonResponse({"ok": False, "errors": form.errors.get_json_data()}, status=400)
|
|
|
|
|
|
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
|
|
|
|
|
|
dovoodi_admin_site.register(CalendarOccasions, CalendarOccasionsAdmin)
|