156 lines
5.1 KiB
Plaintext
156 lines
5.1 KiB
Plaintext
from django.contrib import admin
|
|
from django.utils.translation import gettext_lazy as _
|
|
from nepali.datetime import nepalidate, nepalidatetime
|
|
|
|
from django_nepkit.models import NepaliDateField
|
|
|
|
|
|
def format_nepali_date(date_value, format_string="%B %d, %Y"):
|
|
"""
|
|
Format a nepalidate object with Nepali month names.
|
|
|
|
Args:
|
|
date_value: A nepalidate object or string in YYYY-MM-DD format
|
|
format_string: strftime format string (default: '%B %d, %Y')
|
|
%B = Full month name (Baishak, Jestha, etc.)
|
|
%b = Short month name
|
|
%d = Day of month
|
|
%Y = Year
|
|
|
|
Returns:
|
|
Formatted date string with Nepali month names, or empty string if invalid
|
|
"""
|
|
|
|
if date_value is None:
|
|
return ""
|
|
|
|
try:
|
|
if isinstance(date_value, str):
|
|
date_value = nepalidate.strptime(date_value, "%Y-%m-%d")
|
|
|
|
if isinstance(date_value, nepalidate):
|
|
return date_value.strftime(format_string)
|
|
except (ValueError, TypeError, AttributeError):
|
|
pass
|
|
|
|
return str(date_value) if date_value else ""
|
|
|
|
|
|
def format_nepali_datetime(datetime_value, format_string="%B %d, %Y %I:%M %p"):
|
|
"""
|
|
Format a nepalidatetime object with Nepali month names.
|
|
|
|
Default output uses **12-hour time with AM/PM**.
|
|
"""
|
|
if datetime_value is None:
|
|
return ""
|
|
|
|
try:
|
|
if isinstance(datetime_value, str):
|
|
datetime_value = nepalidatetime.strptime(
|
|
datetime_value, "%Y-%m-%d %H:%M:%S"
|
|
)
|
|
|
|
if isinstance(datetime_value, nepalidatetime):
|
|
return datetime_value.strftime(format_string)
|
|
except (ValueError, TypeError, AttributeError):
|
|
pass
|
|
|
|
return str(datetime_value) if datetime_value else ""
|
|
|
|
|
|
class NepaliDateFilter(admin.FieldListFilter):
|
|
"""
|
|
A list filter for NepaliDateField to filter by BS Year.
|
|
"""
|
|
|
|
def __init__(self, field, request, params, model, model_admin, field_path):
|
|
self.parameter_name = f"{field_path}_bs_year"
|
|
super().__init__(field, request, params, model, model_admin, field_path)
|
|
self.title = _("Nepali Date (Year)")
|
|
|
|
def expected_parameters(self):
|
|
return [self.parameter_name]
|
|
|
|
def choices(self, changelist):
|
|
yield {
|
|
"selected": self.used_parameters.get(self.parameter_name) is None,
|
|
"query_string": changelist.get_query_string(remove=[self.parameter_name]),
|
|
"display": _("All"),
|
|
}
|
|
current_year = nepalidate.today().year
|
|
for year in range(current_year - 10, current_year + 2):
|
|
yield {
|
|
"selected": self.used_parameters.get(self.parameter_name) == str(year),
|
|
"query_string": changelist.get_query_string(
|
|
{self.parameter_name: str(year)}
|
|
),
|
|
"display": str(year),
|
|
}
|
|
|
|
def queryset(self, request, queryset):
|
|
value = self.used_parameters.get(self.parameter_name)
|
|
if value:
|
|
year = int(value)
|
|
# Convert BS year range to AD date range
|
|
start_date_bs = nepalidate(year, 1, 1)
|
|
# Find last day of the year. Some BS years end on the 30th,
|
|
# so we try 31 first and then fall back to 30 if that date
|
|
# is not valid.
|
|
try:
|
|
end_date_bs = nepalidate(year, 12, 31)
|
|
except ValueError:
|
|
end_date_bs = nepalidate(year, 12, 30)
|
|
|
|
start_date_ad = start_date_bs.to_date()
|
|
end_date_ad = end_date_bs.to_date()
|
|
|
|
return queryset.filter(
|
|
**{f"{self.field_path}__range": (start_date_ad, end_date_ad)}
|
|
)
|
|
return queryset
|
|
|
|
|
|
admin.FieldListFilter.register(
|
|
lambda f: isinstance(f, NepaliDateField), NepaliDateFilter, take_priority=True
|
|
)
|
|
|
|
|
|
class NepaliAdminMixin:
|
|
"""
|
|
Mixin for Django admin classes that provides Nepali date utilities.
|
|
Makes format_nepali_date and NepaliDateFilter available without explicit imports.
|
|
"""
|
|
|
|
def format_nepali_date(self, date_value, format_string="%B %d, %Y"):
|
|
"""
|
|
Format a nepalidate object with Nepali month names.
|
|
Available as a method on admin classes using this mixin.
|
|
"""
|
|
return format_nepali_date(date_value, format_string)
|
|
|
|
def format_nepali_datetime(
|
|
self, datetime_value, format_string="%B %d, %Y %I:%M %p"
|
|
):
|
|
return format_nepali_datetime(datetime_value, format_string)
|
|
|
|
|
|
class NepaliModelAdmin(NepaliAdminMixin, admin.ModelAdmin):
|
|
"""
|
|
Base ModelAdmin class with Nepali date utilities built-in.
|
|
Use this instead of admin.ModelAdmin to have format_nepali_date available.
|
|
|
|
Example:
|
|
from django_nepkit import NepaliModelAdmin, NepaliDateFilter
|
|
|
|
@admin.register(MyModel)
|
|
class MyModelAdmin(NepaliModelAdmin):
|
|
list_filter = (('date_field', NepaliDateFilter),)
|
|
|
|
def display_date(self, obj):
|
|
return self.format_nepali_date(obj.date_field)
|
|
"""
|
|
|
|
# Make NepaliDateFilter available as a class attribute
|
|
NepaliDateFilter = NepaliDateFilter
|