django-nepkit 0.1.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. django_nepkit-0.2.1/PKG-INFO +308 -0
  2. django_nepkit-0.2.1/README.md +269 -0
  3. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit/__init__.py +20 -0
  4. django_nepkit-0.2.1/django_nepkit/admin.py +361 -0
  5. django_nepkit-0.2.1/django_nepkit/conf.py +34 -0
  6. django_nepkit-0.2.1/django_nepkit/constants.py +129 -0
  7. django_nepkit-0.2.1/django_nepkit/filters.py +113 -0
  8. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit/forms.py +9 -9
  9. django_nepkit-0.2.1/django_nepkit/lang_utils.py +52 -0
  10. django_nepkit-0.2.1/django_nepkit/models.py +246 -0
  11. django_nepkit-0.2.1/django_nepkit/serializers.py +212 -0
  12. django_nepkit-0.2.1/django_nepkit/static/django_nepkit/js/address-chaining.js +164 -0
  13. django_nepkit-0.2.1/django_nepkit/static/django_nepkit/js/nepal-data.js +1 -0
  14. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit/static/django_nepkit/js/nepali-datepicker-init.js +55 -46
  15. django_nepkit-0.2.1/django_nepkit/utils.py +301 -0
  16. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit/validators.py +1 -1
  17. django_nepkit-0.2.1/django_nepkit/views.py +139 -0
  18. django_nepkit-0.2.1/django_nepkit/widgets.py +141 -0
  19. django_nepkit-0.2.1/django_nepkit.egg-info/PKG-INFO +308 -0
  20. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit.egg-info/SOURCES.txt +6 -8
  21. django_nepkit-0.2.1/django_nepkit.egg-info/requires.txt +8 -0
  22. django_nepkit-0.2.1/example/demo/admin.py +66 -0
  23. django_nepkit-0.2.1/example/demo/models.py +64 -0
  24. django_nepkit-0.2.1/example/demo/serializers.py +39 -0
  25. django_nepkit-0.2.1/example/demo/urls.py +20 -0
  26. django_nepkit-0.2.1/example/demo/views.py +154 -0
  27. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/example/example_project/settings.py +10 -0
  28. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/example/example_project/urls.py +1 -1
  29. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/example/manage.py +2 -2
  30. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/pyproject.toml +12 -5
  31. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/setup.py +2 -2
  32. django_nepkit-0.1.0/PKG-INFO +0 -377
  33. django_nepkit-0.1.0/README.md +0 -340
  34. django_nepkit-0.1.0/django_nepkit/admin.py +0 -211
  35. django_nepkit-0.1.0/django_nepkit/models.py +0 -269
  36. django_nepkit-0.1.0/django_nepkit/serializers.py +0 -113
  37. django_nepkit-0.1.0/django_nepkit/static/django_nepkit/js/address-chaining.js +0 -64
  38. django_nepkit-0.1.0/django_nepkit/templatetags/nepali.py +0 -74
  39. django_nepkit-0.1.0/django_nepkit/utils.py +0 -77
  40. django_nepkit-0.1.0/django_nepkit/views.py +0 -22
  41. django_nepkit-0.1.0/django_nepkit/widgets.py +0 -72
  42. django_nepkit-0.1.0/django_nepkit.egg-info/PKG-INFO +0 -377
  43. django_nepkit-0.1.0/django_nepkit.egg-info/requires.txt +0 -5
  44. django_nepkit-0.1.0/example/demo/admin.py +0 -42
  45. django_nepkit-0.1.0/example/demo/migrations/0001_initial.py +0 -2113
  46. django_nepkit-0.1.0/example/demo/migrations/0002_alter_person_phone_number.py +0 -18
  47. django_nepkit-0.1.0/example/demo/migrations/0003_person_created_at_person_updated_at.py +0 -27
  48. django_nepkit-0.1.0/example/demo/migrations/0004_alter_person_created_at_alter_person_updated_at.py +0 -23
  49. django_nepkit-0.1.0/example/demo/migrations/0005_alter_person_created_at_alter_person_updated_at.py +0 -27
  50. django_nepkit-0.1.0/example/demo/migrations/__init__.py +0 -0
  51. django_nepkit-0.1.0/example/demo/models.py +0 -27
  52. django_nepkit-0.1.0/example/demo/urls.py +0 -9
  53. django_nepkit-0.1.0/example/demo/views.py +0 -32
  54. django_nepkit-0.1.0/example/example_project/__init__.py +0 -0
  55. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/LICENSE +0 -0
  56. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/MANIFEST.in +0 -0
  57. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit/static/django_nepkit/css/admin-nepali-datepicker.css +0 -0
  58. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit/static/django_nepkit/js/admin-jquery-bridge.js +0 -0
  59. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit/urls.py +0 -0
  60. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit.egg-info/dependency_links.txt +0 -0
  61. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/django_nepkit.egg-info/top_level.txt +0 -0
  62. {django_nepkit-0.1.0/django_nepkit/templatetags → django_nepkit-0.2.1/example/demo}/__init__.py +0 -0
  63. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/example/demo/apps.py +0 -0
  64. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/example/demo/tests.py +0 -0
  65. {django_nepkit-0.1.0/example/demo → django_nepkit-0.2.1/example/example_project}/__init__.py +0 -0
  66. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/example/example_project/wsgi.py +0 -0
  67. {django_nepkit-0.1.0 → django_nepkit-0.2.1}/setup.cfg +0 -0
@@ -0,0 +1,308 @@
1
+ Metadata-Version: 2.4
2
+ Name: django-nepkit
3
+ Version: 0.2.1
4
+ Summary: Django Nepali date, time, phone, and address fields with helpers.
5
+ Home-page: https://github.com/S4NKALP/django-nepkit
6
+ Author: Sankalp Tharu
7
+ Author-email: Sankalp Tharu <sankalptharu50028@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/S4NKALP/django-nepkit
10
+ Keywords: django,django-fields,django-forms,nepal,nepali,nepali-date,bikram-sambat,nepali-calendar,timezone,asia-kathmandu,phone-number,address,province,district,municipality
11
+ Classifier: Framework :: Django
12
+ Classifier: Framework :: Django :: 4.2
13
+ Classifier: Framework :: Django :: 5.0
14
+ Classifier: Framework :: Django :: 5.1
15
+ Classifier: Framework :: Django :: 6.0
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Intended Audience :: Developers
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: Utilities
23
+ Classifier: Operating System :: OS Independent
24
+ Classifier: Natural Language :: English
25
+ Requires-Python: >=3.11
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: django>=4.2
29
+ Requires-Dist: django-filter>=25.2
30
+ Requires-Dist: djangorestframework>=3.16.1
31
+ Requires-Dist: nepali>=1.2.0
32
+ Provides-Extra: drf
33
+ Requires-Dist: djangorestframework>=3.14; extra == "drf"
34
+ Requires-Dist: django-filter>=23.1; extra == "drf"
35
+ Dynamic: author
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # 🇳🇵 django-nepkit
41
+
42
+ <div align="center">
43
+
44
+ [![PyPI version](https://badge.fury.io/py/django-nepkit.svg)](https://badge.fury.io/py/django-nepkit)
45
+ [![Python Versions](https://img.shields.io/pypi/pyversions/django-nepkit.svg)](https://pypi.org/project/django-nepkit/)
46
+ [![Django Versions](https://img.shields.io/badge/Django-3.2%20%7C%204.2%20%7C%205.0%20%7C%206.0-blue.svg)](https://www.djangoproject.com/)
47
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
48
+
49
+ **A toolkit for handling BS dates, regional locations, and validation in the local context.**
50
+
51
+ </div>
52
+
53
+ 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.
54
+
55
+ ![Showcase](docs/showcase.gif)
56
+
57
+ ---
58
+
59
+ ## 🎯 Features
60
+
61
+ - **📅 BS Date Support**: Model fields for `nepalidate` and `nepalidatetime` objects.
62
+ - **🗺️ Regional Locations**: Pre-defined Provinces, Districts, and Municipalities.
63
+ - **📱 Phone Validation**: Patterns for local mobile and landline numbers.
64
+ - **💰 Currency Formatting**: `NepaliCurrencyField` with automatic Lakhs/Crores comma placement.
65
+ - **🔤 Numbers to Words**: Convert digits into Nepali text representation.
66
+ - **🔌 Admin Integration**: Automatic setup for datepickers and localized list displays.
67
+ - **🚀 API Support**: DRF Serializers and Filtering backends for BS searching and ordering.
68
+ - **⚡ Location Chaining**: Address linking via client side JS or server driven HTMX.
69
+ - **🔍 Address Normalization**: Utility to extract structured locations from raw strings.
70
+
71
+ ---
72
+
73
+ ## 🛠 Setup
74
+
75
+ Installation:
76
+
77
+ ```bash
78
+ pip install django-nepkit
79
+ ```
80
+
81
+ ### 1. Basic Configuration
82
+
83
+ Add it to your `INSTALLED_APPS`:
84
+
85
+ ```python
86
+ INSTALLED_APPS = [
87
+ # ...
88
+ "django_nepkit",
89
+ ]
90
+ ```
91
+
92
+ ### 2. Global Control
93
+
94
+ Configure behavior in your `settings.py`:
95
+
96
+ ```python
97
+ NEPKIT = {
98
+ "DEFAULT_LANGUAGE": "en", # "en" or "ne"
99
+ "ADMIN_DATEPICKER": True, # Toggle the datepicker
100
+ "TIME_FORMAT": 12, # 12 or 24 hour display
101
+ "DATE_INPUT_FORMATS": ["%Y-%m-%d", "%d/%m/%Y", "%d-%m-%Y"], # Input formats
102
+ }
103
+ ```
104
+
105
+ ---
106
+
107
+ ## 🚀 Core Usage
108
+
109
+ ### 1. Model Implementation
110
+
111
+ Fields store `YYYY-MM-DD` strings for database stability while providing BS objects in Python.
112
+
113
+ ```python
114
+ from django_nepkit import NepaliDateField, NepaliPhoneNumberField
115
+
116
+ class Profile(models.Model):
117
+ name = models.CharField(max_length=100)
118
+ birth_date = NepaliDateField() # BS Date support
119
+ phone = NepaliPhoneNumberField() # Local pattern validation
120
+ ```
121
+
122
+ ### 2. Admin Integration
123
+
124
+ Use `NepaliModelAdmin` for automatic formatting and datepicker support.
125
+
126
+ ```python
127
+ from django_nepkit import NepaliModelAdmin, NepaliDateFilter
128
+
129
+ @admin.register(Profile)
130
+ class ProfileAdmin(NepaliModelAdmin):
131
+ list_display = ("name", "birth_date", "phone")
132
+ list_filter = (("birth_date", NepaliDateFilter),)
133
+ ```
134
+
135
+ ---
136
+
137
+ ## 🗺️ Address Management
138
+
139
+ Manage the **Province → District → Municipality** hierarchy.
140
+
141
+ ### Client-Side Chaining (Standard)
142
+
143
+ Cascading selects in the Django Admin without extra configuration.
144
+
145
+ ```python
146
+ from django_nepkit import ProvinceField, DistrictField, MunicipalityField
147
+
148
+ class Address(models.Model):
149
+ province = ProvinceField()
150
+ district = DistrictField()
151
+ municipality = MunicipalityField()
152
+
153
+ ### Address Normalization
154
+
155
+ Standardize raw strings into structured location data (Province, District, Municipality).
156
+
157
+ ```python
158
+ from django_nepkit.utils import normalize_address
159
+
160
+ # Supports English or Nepali input
161
+ result = normalize_address("House 123, Bharatpur, Chitwan")
162
+ # Returns: {'province': 'Bagmati Province', 'district': 'Chitawan', 'municipality': 'Bharatpur Metropolitan City'}
163
+
164
+ result_ne = normalize_address("विराटनगर, कोशी")
165
+ # Returns: {'province': 'कोशी प्रदेश', 'district': 'मोरङ', 'municipality': 'विराटनगर महानगरपालिका'}
166
+ ```
167
+ ```
168
+
169
+ ### Server Side Chaining (HTMX)
170
+
171
+ Enable `htmx=True` for a server driven experience.
172
+
173
+ > [!IMPORTANT]
174
+ > **HTMX Setup:**
175
+ > Include the required URLs in your main `urls.py`:
176
+ >
177
+ > ```python
178
+ > path("nepkit/", include("django_nepkit.urls")),
179
+ > ```
180
+
181
+ ---
182
+
183
+ ## 🔌 API & DRF Support
184
+
185
+ Search and ordering work natively. BS year/month filtering is supported.
186
+
187
+ ```python
188
+ from django_nepkit.filters import NepaliDateYearFilter
189
+
190
+ class ProfileFilter(filters.FilterSet):
191
+ # Filter by BS Year (e.g., /api/profiles/?year=2081)
192
+ year = NepaliDateYearFilter(field_name="birth_date")
193
+ ```
194
+
195
+ ---
196
+
197
+ ## 💰 Formatting & Helpers
198
+
199
+ ### 1. Currency & Numbers
200
+ Use `NepaliCurrencyField` for automatic formatting in the admin and templates.
201
+
202
+ ```python
203
+ from django_nepkit import NepaliCurrencyField
204
+
205
+ class Transaction(models.Model):
206
+ amount = NepaliCurrencyField() # Defaults to 19 digits, 2 decimals
207
+ ```
208
+
209
+ ### 2. Template Filters
210
+ Load the tags to use localized formatting in your templates.
211
+
212
+ ```html
213
+ {% load nepali %}
214
+
215
+ <!-- Comma formatting: Rs. 1,12,000.00 -->
216
+ <p>{{ 112000 | nepali_currency }}</p>
217
+
218
+ <!-- Numbers to Words: एक सय तेईस -->
219
+ <p>{{ 123 | nepali_words }}</p>
220
+
221
+ <!-- English to Nepali Digits: १२३ -->
222
+ <p>{{ "123" | nepali_unicode }}</p>
223
+ ```
224
+
225
+ ---
226
+
227
+ ## 🕒 Technical Design
228
+
229
+ This library is engineered for performance, data integrity, and local compliance.
230
+
231
+ ### 1. The "Source of Truth" Strategy
232
+ 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).
233
+ - **Storage**: All BS dates are stored as `VARCHAR(10)` in `YYYY-MM-DD` format.
234
+ - **Sorting**: Because `YYYY` is at the start, string based database sorting (ascending/descending) accurately matches chronological order.
235
+ - **Indexability**: Standard B-Tree indexes work perfectly on these fields without requiring custom database functions.
236
+ - **Timezone Safety**: Dates are stored without time components, making them immune to server side timezone shifts during saving.
237
+
238
+ ### 2. Python Object Mapping
239
+ While data is stored as strings, it is automatically hydrated into rich Python objects.
240
+ - **`nepali-datetime` Integration**: Values are cast to `nepalidate` or `nepalidatetime` objects when retrieved from the database.
241
+ - **Validation**: Fields use specialized validators (e.g., `validate_nepali_phone_number`) that leverage official regional patterns.
242
+
243
+ ### 3. Frontend Architecture
244
+ - **Automatic Initialization**: The library includes a lightweight JS observer that automatically initializes the datepicker for any field with the `.nepkit-datepicker` class.
245
+ - **Theme Support**: The datepicker dynamically adapts its skin based on the Django Admin's dark/light mode state.
246
+
247
+ ---
248
+
249
+ ## ❓ FAQ
250
+
251
+ **Q: How do I handle Null or Optional dates?**
252
+
253
+ Just like standard Django fields, pass `null=True, blank=True` to any `django-nepkit` field. The library handles empty strings and `None` values gracefully.
254
+
255
+ **Q: Can I change the database storage format?**
256
+
257
+ 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.
258
+
259
+ **Q: Can I use Devanagari output?**
260
+
261
+ Yes. Pass `ne=True` to fields, forms, or serializers.
262
+
263
+ **Q: Can I display the datepicker in English?**
264
+
265
+ Yes. By default, if you pass `en=True` (or if `DEFAULT_LANGUAGE` is set to `"en"`), the datepicker will display month and day names in English instead of Devanagari script.
266
+
267
+ ```python
268
+ birth_date = NepaliDateField(en=True) # English month/day names in picker
269
+ ```
270
+
271
+ **Q: Is the location data up to date?**
272
+
273
+ Yes. Province, District, and Municipality data is sourced from the `nepali` Python package, which is regularly updated to reflect administrative changes in Nepal.
274
+
275
+ **Q: Does it work with standard Django Forms?**
276
+
277
+ Yes. `NepaliDateField` uses a specialized `NepaliDateFormField` that automatically handles input parsing and error reporting.
278
+
279
+ **Q: How do I migrate existing English (AD) dates to BS?**
280
+
281
+ We recommend staying on standard `DateField` for AD data. If you must convert to BS, use our [Migration Script](docs/migration_guide.py) to perform a bulk data transformation safely.
282
+
283
+ **Q: Why use VARCHAR instead of a native DateField?**
284
+
285
+ 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.
286
+
287
+ ---
288
+
289
+ ## 🤝 Community
290
+
291
+ We welcome contributions and feedback from the community.
292
+
293
+ 1. **Clone**: `git clone https://github.com/S4NKALP/django-nepkit`
294
+ 2. **Setup**: `uv sync`
295
+ 3. **Test**: `uv run pytest`
296
+
297
+ ---
298
+
299
+ ## 🙏 Credits
300
+
301
+ This library is built on top of excellent open source projects:
302
+
303
+ - **[nepali](https://github.com/opensource-nepal/py-nepali)** by [@opensource-nepal](https://github.com/opensource-nepal) - Provides the core `nepalidate`, `nepalidatetime` objects and regional location data (Provinces, Districts, Municipalities).
304
+ - **[Nepali Datepicker](https://nepalidatepicker.sajanmaharjan.com.np/)** by [Sajan Maharjan](https://github.com/sajanm/nepali-date-picker) - Powers the beautiful BS date picker widget in the Django Admin.
305
+
306
+ ---
307
+
308
+ MIT License. Designed for the local Django ecosystem.
@@ -0,0 +1,269 @@
1
+ # 🇳🇵 django-nepkit
2
+
3
+ <div align="center">
4
+
5
+ [![PyPI version](https://badge.fury.io/py/django-nepkit.svg)](https://badge.fury.io/py/django-nepkit)
6
+ [![Python Versions](https://img.shields.io/pypi/pyversions/django-nepkit.svg)](https://pypi.org/project/django-nepkit/)
7
+ [![Django Versions](https://img.shields.io/badge/Django-3.2%20%7C%204.2%20%7C%205.0%20%7C%206.0-blue.svg)](https://www.djangoproject.com/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ **A toolkit for handling BS dates, regional locations, and validation in the local context.**
11
+
12
+ </div>
13
+
14
+ 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.
15
+
16
+ ![Showcase](docs/showcase.gif)
17
+
18
+ ---
19
+
20
+ ## 🎯 Features
21
+
22
+ - **📅 BS Date Support**: Model fields for `nepalidate` and `nepalidatetime` objects.
23
+ - **🗺️ Regional Locations**: Pre-defined Provinces, Districts, and Municipalities.
24
+ - **📱 Phone Validation**: Patterns for local mobile and landline numbers.
25
+ - **💰 Currency Formatting**: `NepaliCurrencyField` with automatic Lakhs/Crores comma placement.
26
+ - **🔤 Numbers to Words**: Convert digits into Nepali text representation.
27
+ - **🔌 Admin Integration**: Automatic setup for datepickers and localized list displays.
28
+ - **🚀 API Support**: DRF Serializers and Filtering backends for BS searching and ordering.
29
+ - **⚡ Location Chaining**: Address linking via client side JS or server driven HTMX.
30
+ - **🔍 Address Normalization**: Utility to extract structured locations from raw strings.
31
+
32
+ ---
33
+
34
+ ## 🛠 Setup
35
+
36
+ Installation:
37
+
38
+ ```bash
39
+ pip install django-nepkit
40
+ ```
41
+
42
+ ### 1. Basic Configuration
43
+
44
+ Add it to your `INSTALLED_APPS`:
45
+
46
+ ```python
47
+ INSTALLED_APPS = [
48
+ # ...
49
+ "django_nepkit",
50
+ ]
51
+ ```
52
+
53
+ ### 2. Global Control
54
+
55
+ Configure behavior in your `settings.py`:
56
+
57
+ ```python
58
+ NEPKIT = {
59
+ "DEFAULT_LANGUAGE": "en", # "en" or "ne"
60
+ "ADMIN_DATEPICKER": True, # Toggle the datepicker
61
+ "TIME_FORMAT": 12, # 12 or 24 hour display
62
+ "DATE_INPUT_FORMATS": ["%Y-%m-%d", "%d/%m/%Y", "%d-%m-%Y"], # Input formats
63
+ }
64
+ ```
65
+
66
+ ---
67
+
68
+ ## 🚀 Core Usage
69
+
70
+ ### 1. Model Implementation
71
+
72
+ Fields store `YYYY-MM-DD` strings for database stability while providing BS objects in Python.
73
+
74
+ ```python
75
+ from django_nepkit import NepaliDateField, NepaliPhoneNumberField
76
+
77
+ class Profile(models.Model):
78
+ name = models.CharField(max_length=100)
79
+ birth_date = NepaliDateField() # BS Date support
80
+ phone = NepaliPhoneNumberField() # Local pattern validation
81
+ ```
82
+
83
+ ### 2. Admin Integration
84
+
85
+ Use `NepaliModelAdmin` for automatic formatting and datepicker support.
86
+
87
+ ```python
88
+ from django_nepkit import NepaliModelAdmin, NepaliDateFilter
89
+
90
+ @admin.register(Profile)
91
+ class ProfileAdmin(NepaliModelAdmin):
92
+ list_display = ("name", "birth_date", "phone")
93
+ list_filter = (("birth_date", NepaliDateFilter),)
94
+ ```
95
+
96
+ ---
97
+
98
+ ## 🗺️ Address Management
99
+
100
+ Manage the **Province → District → Municipality** hierarchy.
101
+
102
+ ### Client-Side Chaining (Standard)
103
+
104
+ Cascading selects in the Django Admin without extra configuration.
105
+
106
+ ```python
107
+ from django_nepkit import ProvinceField, DistrictField, MunicipalityField
108
+
109
+ class Address(models.Model):
110
+ province = ProvinceField()
111
+ district = DistrictField()
112
+ municipality = MunicipalityField()
113
+
114
+ ### Address Normalization
115
+
116
+ Standardize raw strings into structured location data (Province, District, Municipality).
117
+
118
+ ```python
119
+ from django_nepkit.utils import normalize_address
120
+
121
+ # Supports English or Nepali input
122
+ result = normalize_address("House 123, Bharatpur, Chitwan")
123
+ # Returns: {'province': 'Bagmati Province', 'district': 'Chitawan', 'municipality': 'Bharatpur Metropolitan City'}
124
+
125
+ result_ne = normalize_address("विराटनगर, कोशी")
126
+ # Returns: {'province': 'कोशी प्रदेश', 'district': 'मोरङ', 'municipality': 'विराटनगर महानगरपालिका'}
127
+ ```
128
+ ```
129
+
130
+ ### Server Side Chaining (HTMX)
131
+
132
+ Enable `htmx=True` for a server driven experience.
133
+
134
+ > [!IMPORTANT]
135
+ > **HTMX Setup:**
136
+ > Include the required URLs in your main `urls.py`:
137
+ >
138
+ > ```python
139
+ > path("nepkit/", include("django_nepkit.urls")),
140
+ > ```
141
+
142
+ ---
143
+
144
+ ## 🔌 API & DRF Support
145
+
146
+ Search and ordering work natively. BS year/month filtering is supported.
147
+
148
+ ```python
149
+ from django_nepkit.filters import NepaliDateYearFilter
150
+
151
+ class ProfileFilter(filters.FilterSet):
152
+ # Filter by BS Year (e.g., /api/profiles/?year=2081)
153
+ year = NepaliDateYearFilter(field_name="birth_date")
154
+ ```
155
+
156
+ ---
157
+
158
+ ## 💰 Formatting & Helpers
159
+
160
+ ### 1. Currency & Numbers
161
+ Use `NepaliCurrencyField` for automatic formatting in the admin and templates.
162
+
163
+ ```python
164
+ from django_nepkit import NepaliCurrencyField
165
+
166
+ class Transaction(models.Model):
167
+ amount = NepaliCurrencyField() # Defaults to 19 digits, 2 decimals
168
+ ```
169
+
170
+ ### 2. Template Filters
171
+ Load the tags to use localized formatting in your templates.
172
+
173
+ ```html
174
+ {% load nepali %}
175
+
176
+ <!-- Comma formatting: Rs. 1,12,000.00 -->
177
+ <p>{{ 112000 | nepali_currency }}</p>
178
+
179
+ <!-- Numbers to Words: एक सय तेईस -->
180
+ <p>{{ 123 | nepali_words }}</p>
181
+
182
+ <!-- English to Nepali Digits: १२३ -->
183
+ <p>{{ "123" | nepali_unicode }}</p>
184
+ ```
185
+
186
+ ---
187
+
188
+ ## 🕒 Technical Design
189
+
190
+ This library is engineered for performance, data integrity, and local compliance.
191
+
192
+ ### 1. The "Source of Truth" Strategy
193
+ 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).
194
+ - **Storage**: All BS dates are stored as `VARCHAR(10)` in `YYYY-MM-DD` format.
195
+ - **Sorting**: Because `YYYY` is at the start, string based database sorting (ascending/descending) accurately matches chronological order.
196
+ - **Indexability**: Standard B-Tree indexes work perfectly on these fields without requiring custom database functions.
197
+ - **Timezone Safety**: Dates are stored without time components, making them immune to server side timezone shifts during saving.
198
+
199
+ ### 2. Python Object Mapping
200
+ While data is stored as strings, it is automatically hydrated into rich Python objects.
201
+ - **`nepali-datetime` Integration**: Values are cast to `nepalidate` or `nepalidatetime` objects when retrieved from the database.
202
+ - **Validation**: Fields use specialized validators (e.g., `validate_nepali_phone_number`) that leverage official regional patterns.
203
+
204
+ ### 3. Frontend Architecture
205
+ - **Automatic Initialization**: The library includes a lightweight JS observer that automatically initializes the datepicker for any field with the `.nepkit-datepicker` class.
206
+ - **Theme Support**: The datepicker dynamically adapts its skin based on the Django Admin's dark/light mode state.
207
+
208
+ ---
209
+
210
+ ## ❓ FAQ
211
+
212
+ **Q: How do I handle Null or Optional dates?**
213
+
214
+ Just like standard Django fields, pass `null=True, blank=True` to any `django-nepkit` field. The library handles empty strings and `None` values gracefully.
215
+
216
+ **Q: Can I change the database storage format?**
217
+
218
+ 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.
219
+
220
+ **Q: Can I use Devanagari output?**
221
+
222
+ Yes. Pass `ne=True` to fields, forms, or serializers.
223
+
224
+ **Q: Can I display the datepicker in English?**
225
+
226
+ Yes. By default, if you pass `en=True` (or if `DEFAULT_LANGUAGE` is set to `"en"`), the datepicker will display month and day names in English instead of Devanagari script.
227
+
228
+ ```python
229
+ birth_date = NepaliDateField(en=True) # English month/day names in picker
230
+ ```
231
+
232
+ **Q: Is the location data up to date?**
233
+
234
+ Yes. Province, District, and Municipality data is sourced from the `nepali` Python package, which is regularly updated to reflect administrative changes in Nepal.
235
+
236
+ **Q: Does it work with standard Django Forms?**
237
+
238
+ Yes. `NepaliDateField` uses a specialized `NepaliDateFormField` that automatically handles input parsing and error reporting.
239
+
240
+ **Q: How do I migrate existing English (AD) dates to BS?**
241
+
242
+ We recommend staying on standard `DateField` for AD data. If you must convert to BS, use our [Migration Script](docs/migration_guide.py) to perform a bulk data transformation safely.
243
+
244
+ **Q: Why use VARCHAR instead of a native DateField?**
245
+
246
+ 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.
247
+
248
+ ---
249
+
250
+ ## 🤝 Community
251
+
252
+ We welcome contributions and feedback from the community.
253
+
254
+ 1. **Clone**: `git clone https://github.com/S4NKALP/django-nepkit`
255
+ 2. **Setup**: `uv sync`
256
+ 3. **Test**: `uv run pytest`
257
+
258
+ ---
259
+
260
+ ## 🙏 Credits
261
+
262
+ This library is built on top of excellent open source projects:
263
+
264
+ - **[nepali](https://github.com/opensource-nepal/py-nepali)** by [@opensource-nepal](https://github.com/opensource-nepal) - Provides the core `nepalidate`, `nepalidatetime` objects and regional location data (Provinces, Districts, Municipalities).
265
+ - **[Nepali Datepicker](https://nepalidatepicker.sajanmaharjan.com.np/)** by [Sajan Maharjan](https://github.com/sajanm/nepali-date-picker) - Powers the beautiful BS date picker widget in the Django Admin.
266
+
267
+ ---
268
+
269
+ MIT License. Designed for the local Django ecosystem.
@@ -6,14 +6,26 @@ from .models import (
6
6
  ProvinceField,
7
7
  DistrictField,
8
8
  MunicipalityField,
9
+ NepaliCurrencyField,
9
10
  )
10
11
  from .admin import (
11
12
  NepaliDateFilter,
13
+ NepaliMonthFilter,
12
14
  format_nepali_date,
13
15
  format_nepali_datetime,
14
16
  NepaliModelAdmin,
15
17
  NepaliAdminMixin,
16
18
  )
19
+ from .serializers import (
20
+ NepaliCurrencySerializerField,
21
+ NepaliLocalizedSerializerMixin,
22
+ )
23
+ from .filters import (
24
+ NepaliDateYearFilter,
25
+ NepaliDateMonthFilter,
26
+ NepaliDateRangeFilter,
27
+ NepaliCurrencyRangeFilter,
28
+ )
17
29
 
18
30
  __all__ = [
19
31
  "NepaliDateField",
@@ -24,8 +36,16 @@ __all__ = [
24
36
  "DistrictField",
25
37
  "MunicipalityField",
26
38
  "NepaliDateFilter",
39
+ "NepaliMonthFilter",
27
40
  "format_nepali_date",
28
41
  "format_nepali_datetime",
29
42
  "NepaliModelAdmin",
30
43
  "NepaliAdminMixin",
44
+ "NepaliCurrencyField",
45
+ "NepaliCurrencySerializerField",
46
+ "NepaliLocalizedSerializerMixin",
47
+ "NepaliDateYearFilter",
48
+ "NepaliDateMonthFilter",
49
+ "NepaliDateRangeFilter",
50
+ "NepaliCurrencyRangeFilter",
31
51
  ]