Files
django-nepkit/django_nepkit/utils.py
T
sankalp 09f302ceaa feat: implement HTMX support, DRF filters, and professionalized documentation
- Implement server-side location chaining with HTMX support via `htmx=True` in fields and widgets.
- Update location views to handle HTMX requests and return HTML <option> fragments.
- Add NepaliDateYearFilter and NepaliDateRangeFilter for robust DRF API filtering.
- Expand default `DATE_INPUT_FORMATS` in configuration to support multiple common Nepali date styles.
- Update DRF serializers to automatically respect global `NEPKIT` configuration settings.
- Add `django-filter` as an optional dependency under the `drf` extra in pyproject.toml.
- Correct underlying dependency references from `nepali-datetime` to nepali library.
- Complete overhaul of README.md for premium DX, including new sections for storage behavior, timezone awareness, and API usage.
2026-01-30 15:22:13 +05:45

100 lines
3.0 KiB
Python

from __future__ import annotations
from typing import Any, Optional
from nepali.datetime import nepalidate, nepalidatetime
from nepali.locations import districts, provinces
from django_nepkit.conf import nepkit_settings
BS_DATE_FORMAT = "%Y-%m-%d"
BS_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
def _try_parse_nepali(value: Any, cls: Any, fallback_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):
formats = nepkit_settings.DATE_INPUT_FORMATS
if fallback_fmt not in formats:
formats = list(formats) + [fallback_fmt]
for fmt in formats:
try:
return cls.strptime(value.strip(), fmt)
except Exception:
continue
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:
p_name = p.name
p_name_ne = getattr(p, "name_nepali", None)
# Mapping fix for lookups
if parent_name == "Koshi Province":
if p_name == "Province 1":
selected_parent = p
break
elif parent_name == "कोशी प्रदेश":
if p_name_ne == "प्रदेश नं. १":
selected_parent = p
break
if p_name == parent_name or p_name_ne == 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)