sankalp 1338f9e5fe refactor: global project refinement, DRY consolidation, and documentation overhaul
This commit represents a comprehensive improvement of the library's architecture, developer experience, and documentation accuracy.

Core Refactoring:
- apply DRY principle to models.py by introducing BaseNepaliBSField and BaseLocationField
- standardize widget logic in widgets.py using NepaliWidgetMixin
- centralize admin filtering logic into BaseNepaliDateFilter

New Features & API:
- add NepaliMonthFilter for Django Admin and NepaliDateMonthFilter for DRF
- implementation of HTMX-driven location chaining for dynamic address selects
- extend demo project with comprehensive DRF search, ordering, and filter examples

Configuration & Sync:
- implement global NEPKIT settings in conf.py (DEFAULT_LANGUAGE, ADMIN_DATEPICKER, etc.)
- universalize BS_DATE_FORMAT/BS_DATETIME_FORMAT across the entire stack
- synchronize frontend datepicker initialization with backend date formats

Documentation & DX:
- complete rewrite of README.md into high-energy, factual, English-only guides
- project-wide audit and simplification of comments/docstrings for beginner accessibility
- expanded 'Technical Design' and 'FAQ' sections covering data integrity and storage
- added docs/migration_guide.py for bulk AD-to-BS data transitions

Quality & Maintenance:
- fixed all E402 module-level import errors across the library
- verified codebase with project-wide ruff checks (all checks passed)
2026-01-30 17:00:33 +05:45
2026-01-28 20:08:35 +05:45
2026-01-29 02:05:18 +05:45

🇳🇵 django-nepkit

PyPI version Python Versions Django Versions License: MIT

A toolkit for handling BS dates, regional locations, and validation in the local context.

Building software for local requirements comes with unique challenges—from handling BS dates to managing the regional administrative hierarchy. django-nepkit provides solutions for these requirements directly within the Django ecosystem.


🎯 Features

  • 📅 BS Date Support: Model fields for nepalidate and nepalidatetime objects.
  • 🗺️ Regional Locations: Pre-defined Provinces, Districts, and Municipalities.
  • 📱 Phone Validation: Patterns for local mobile and landline numbers.
  • 🔌 Admin Integration: Automatic setup for datepickers and localized list displays.
  • 🚀 API Support: DRF Serializers and Filtering backends for BS searching and ordering.
  • ⚡ Location Chaining: Address linking via client-side JS or server-driven HTMX.

🛠 Setup

Installation:

pip install django-nepkit

1. Basic Configuration

Add it to your INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    "django_nepkit",
]

2. Global Control

Configure behavior in your settings.py:

NEPKIT = {
    "DEFAULT_LANGUAGE": "en",           # "en" or "ne"
    "ADMIN_DATEPICKER": True,           # Toggle the datepicker
    "TIME_FORMAT": 12,                  # 12 or 24 hour display
    "DATE_INPUT_FORMATS": ["%Y-%m-%d", "%d/%m/%Y", "%d-%m-%Y"], # Input formats
}

🚀 Core Usage

1. Model Implementation

Fields store YYYY-MM-DD strings for database stability while providing BS objects in Python.

from django_nepkit import NepaliDateField, NepaliPhoneNumberField

class Profile(models.Model):
    name = models.CharField(max_length=100)
    birth_date = NepaliDateField() # BS Date support
    phone = NepaliPhoneNumberField() # Local pattern validation

2. Admin Integration

Use NepaliModelAdmin for automatic formatting and datepicker support.

from django_nepkit import NepaliModelAdmin, NepaliDateFilter

@admin.register(Profile)
class ProfileAdmin(NepaliModelAdmin):
    list_display = ("name", "birth_date", "phone")
    list_filter = (("birth_date", NepaliDateFilter),)

🗺️ Address Management

Manage the Province → District → Municipality hierarchy.

Client-Side Chaining (Standard)

Cascading selects in the Django Admin without extra configuration.

from django_nepkit import ProvinceField, DistrictField, MunicipalityField

class Address(models.Model):
    province = ProvinceField()
    district = DistrictField()
    municipality = MunicipalityField()

Server-Side Chaining (HTMX)

Enable htmx=True for a server-driven experience.

Important

HTMX Setup: Include the required URLs in your main urls.py:

path("nepkit/", include("django_nepkit.urls")),

🔌 API & DRF Support

Search and ordering work natively. BS year/month filtering is supported.

from django_nepkit.filters import NepaliDateYearFilter

class ProfileFilter(filters.FilterSet):
    # Filter by BS Year (e.g., /api/profiles/?year=2081)
    year = NepaliDateYearFilter(field_name="birth_date")

🕒 Technical Design

This library is engineered for performance, data integrity, and local compliance.

1. The "Source of Truth" Strategy

We avoid on-the-fly AD-to-BS conversion during database queries because it is computationally expensive and prone to logical drift (due to lunar calendar offsets).

  • Storage: All BS dates are stored as VARCHAR(10) in YYYY-MM-DD format.
  • Sorting: Because YYYY is at the start, string-based database sorting (ascending/descending) accurately matches chronological order.
  • Indexability: Standard B-Tree indexes work perfectly on these fields without requiring custom database functions.
  • Timezone Safety: Dates are stored without time components, making them immune to server-side timezone shifts during saving.

2. Python Object Mapping

While data is stored as strings, it is automatically hydrated into rich Python objects.

  • nepali-datetime Integration: Values are cast to nepalidate or nepalidatetime objects when retrieved from the database.
  • Validation: Fields use specialized validators (e.g., validate_nepali_phone_number) that leverage official regional patterns.

3. Frontend Architecture

  • Automatic Initialization: The library includes a lightweight JS observer that automatically initializes the datepicker for any field with the .nepkit-datepicker class.
  • Theme Support: The datepicker dynamically adapts its skin based on the Django Admin's dark/light mode state.

❓ FAQ

Q: How do I handle Null or Optional dates? Just like standard Django fields, pass null=True, blank=True to any django-nepkit field. The library handles empty strings and None values gracefully.

Q: Can I change the database storage format? No. The YYYY-MM-DD format is hardcoded to ensure database-level sorting and indexing work consistently. However, you can change the display format via global settings or template filters.

Q: How do I get Devanagari (local script) digits in my API? In your Serializer field or Model field, pass ne=True.

birth_date = NepaliDateField(ne=True)

Q: Is the location data up to date? Yes. Province, District, and Municipality data is sourced from the nepali Python package, which is regularly updated to reflect administrative changes in Nepal.

Q: Does it work with standard Django Forms? Yes. NepaliDateField uses a specialized NepaliDateFormField that automatically handles input parsing and error reporting.

Q: How do I migrate existing English (AD) dates to BS? We recommend staying on standard DateField for AD data. If you must convert to BS, use our Migration Script to perform a bulk data transformation safely.

Q: Why use VARCHAR instead of a native DateField? Native DateField in most SQL engines is locked to the Gregorian calendar. Using VARCHAR allows us to treat the BS date as the primary data point, avoiding the "off-by-one" conversion errors common when syncing two disparate calendars.


🤝 Community

We welcome contributions and feedback from the community.

  1. Clone: git clone https://github.com/S4NKALP/django-nepkit
  2. Setup: uv sync
  3. Test: uv run pytest

📄 License

MIT License. Designed for the local Django ecosystem.

V.0.2.2
Latest
2026-06-06 16:10:38 +00:00
Languages
Python 87.5%
JavaScript 9.1%
HTML 2.7%
CSS 0.5%
Makefile 0.2%