Implemented a comprehensive update to handle Nepali (Bikram Sambat) localization more robustly across models, forms, admin, and API serializers. This includes native support for Devanagari script output and a complete documentation overhaul. Models & Fields: - Added [NepaliFieldMixin](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/models.py:15:0-36:39) to support [ne](cci:1://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/admin.py:146:4-163:67) (Nepali) and [en](cci:1://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/widgets.py:4:0-10:16) (English) toggles for all custom fields. - Updated [NepaliDateField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/models.py:48:0-134:44), [NepaliDateTimeField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/models.py:144:0-217:44), and [NepaliTimeField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/models.py:137:0-141:34) with the new mixin and improved deconstruction. - Enhanced address fields ([ProvinceField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/models.py:220:0-262:23), [DistrictField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/models.py:265:0-286:66), [MunicipalityField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/models.py:289:0-310:66)) to support bilingual choices. Admin Enhancements: - Refactored date formatting into a common utility supporting Devanagari via `strftime_ne`. - Updated [NepaliModelAdmin](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/admin.py:186:0-294:9) and [NepaliAdminMixin](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/admin.py:118:0-183:75) to auto-detect [ne](cci:1://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/admin.py:146:4-163:67) settings from model fields for [list_display](cci:1://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/admin.py:230:4-250:21). - Improved widget injection in the admin to respect field-level localization settings. - Added a JS bridge for admin jQuery compatibility with the Nepali datepicker. Forms & Widgets: - Introduced [NepaliWidgetMixin](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/widgets.py:13:0-38:12) to handle localization data attributes in the frontend. - Updated [NepaliDatePickerWidget](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/widgets.py:63:0-99:42) with improved asset loading and Devanagari support. - Fixed [NepaliDateFormField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/forms.py:10:0-41:13) to correctly handle `empty_value` passed by the Django admin. DRF (Serializers): - Added [BaseNepaliBSField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/serializers.py:21:0-106:48) to DRF serializers with support for `ne=True` for Devanagari output. - Implemented specialized [NepaliDateSerializerField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/serializers.py:114:0-122:28) and [NepaliDateTimeSerializerField](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/serializers.py:130:0-138:32). Documentation: - Completely revamped [README.md](cci:7://file:///home/sankalp/Projects/prod-django-nepkit/README.md:0:0-0:0) with professional design, badges, and detailed usage guides. - Added explicit instructions for address chaining URLs and [NepaliAdminMixin](cci:2://file:///home/sankalp/Projects/prod-django-nepkit/django_nepkit/admin.py:118:0-183:75) usage. Misc: - Optimized address chaining JS logic. - Updated example demo app models and migrations to reflect new field capabilities.
80 lines
2.3 KiB
Python
80 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, Optional
|
|
|
|
from nepali.datetime import nepalidate, nepalidatetime
|
|
from nepali.locations import districts, provinces
|
|
|
|
BS_DATE_FORMAT = "%Y-%m-%d"
|
|
BS_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
|
|
|
|
|
|
def _try_parse_nepali(value: Any, cls: Any, fmt: str) -> Any:
|
|
"""Internal helper to parse Nepali date/datetime."""
|
|
if value in (None, ""):
|
|
return None
|
|
if isinstance(value, cls):
|
|
return value
|
|
if isinstance(value, str):
|
|
try:
|
|
return cls.strptime(value.strip(), fmt)
|
|
except Exception:
|
|
return None
|
|
return None
|
|
|
|
|
|
def try_parse_nepali_date(value: Any) -> Optional[nepalidate]:
|
|
"""
|
|
Best-effort conversion to `nepalidate`.
|
|
"""
|
|
return _try_parse_nepali(value, nepalidate, BS_DATE_FORMAT)
|
|
|
|
|
|
def try_parse_nepali_datetime(value: Any) -> Optional[nepalidatetime]:
|
|
"""
|
|
Best-effort conversion to `nepalidatetime`.
|
|
"""
|
|
return _try_parse_nepali(value, nepalidatetime, BS_DATETIME_FORMAT)
|
|
|
|
|
|
def _get_location_children(parent_list, parent_name, child_attr, ne=False):
|
|
"""
|
|
Internal helper to finding a parent in a list and returning its children (districts/municipalities).
|
|
"""
|
|
selected_parent = None
|
|
for p in parent_list:
|
|
if p.name == parent_name or getattr(p, "name_nepali", None) == parent_name:
|
|
selected_parent = p
|
|
break
|
|
|
|
if not selected_parent:
|
|
return []
|
|
|
|
children = getattr(selected_parent, child_attr, [])
|
|
|
|
if ne:
|
|
return [
|
|
{
|
|
"id": getattr(child, "name_nepali", child.name),
|
|
"text": getattr(child, "name_nepali", child.name),
|
|
}
|
|
for child in children
|
|
]
|
|
else:
|
|
return [{"id": child.name, "text": child.name} for child in children]
|
|
|
|
|
|
def get_districts_by_province(province_name, ne=False, en=True):
|
|
"""
|
|
Returns a list of districts in the given province.
|
|
"""
|
|
# Logic note: if ne=True is passed, we shouldn't care about en=True (handled by caller typically)
|
|
return _get_location_children(provinces, province_name, "districts", ne=ne)
|
|
|
|
|
|
def get_municipalities_by_district(district_name, ne=False, en=True):
|
|
"""
|
|
Returns a list of municipalities in the given district.
|
|
"""
|
|
return _get_location_children(districts, district_name, "municipalities", ne=ne)
|