drop DRF and django-filter to make django_nepkit framework‑agnostic, simplify dependencies, and align with v0.2.2 breaking change.
9.1 KiB
9.1 KiB
V.0.2.2 — 2026-06-06
💥 Breaking changes
- Drop DRF and django-filter dependencies. The package no longer ships
django_nepkit.serializers,django_nepkit.ninja, ordjango_nepkit.filters. All serialization is now exposed as framework-agnostic helpers indjango_nepkit.api(seeserialize_nepali_date,serialize_nepali_time,serialize_nepali_currency,build_localized_payload, etc.). If you were using the DRFNepaliDateSerializerField/NepaliCurrencySerializerFieldor theNepaliDateYearFilter/NepaliDateMonthFilter/ range filters, write a thin adapter againstdjango_nepkit.api(or just use plain Django views — see the updatedexample/demo). BaseNepaliBSField.to_pythonandget_prep_valuenow raiseValidationErroron bad input instead of silently returningstr(value). Code that was relying on the silent passthrough (e.g. persisting"not-a-date"strings to the DB) will now fail loudly at the form / save boundary, which is the correct behaviour.format_nepali_currencyandnumber_to_nepali_wordsnow raiseValueErroron un-parseable input instead of returningstr(value)/ crashing withIndexErroron negative numbers. Negative numbers are now rendered as"ऋणात्मक …".
✨ Features
- New
NepaliTimeField(realTimeFieldwith Devanagari digit output,auto_now/auto_now_addsupport,BS_TIME_FORMATsetting). - New
NepaliTimeWidgetand JS init for client-side time validation. - New
strictflag on everydjango_nepkit.api.serialize_*/deserialize_*and onto_decimalfor callers that want to opt into hard validation errors instead of best-effort passthrough. - Admin address-chaining fixed: districts / municipalities are now filtered on init when a parent value is preselected (e.g. when editing an existing record).
MunicipalitySelectWidgetnow also supportshtmx=Truelike its district sibling._render_optionsescapes its HTML output viaformat_html/format_html_join(XSS fix).BaseLocationField.choicesis now a live property that re-evaluates on every access from the currentnepkit_settings. An explicitne=True/ne=Falseconstructor arg pins the language for the field's lifetime (only the implicit default re-reads the setting).refresh_choices()is kept as a no-op for backwards compatibility.normalize_addressis now backed by anlru_cache(1024)-decorated inner function so the heavy_find_location_in_tokenswork runs at most once per unique address string. The public function still returns a fresh dict per call so callers can mutate safely.- Demo JSON views (
person_api,audited_api,transaction_api) accept?strict=1to threadstrict=Truethrough theserialize_nepali_date/serialize_nepali_datetimecalls — handy for smoke-testing the strict path against live data. NEPKIT_ONESconstantNEGATIVE_PREFIXis now part of the public API for callers that want to render negative numbers themselves.
🐛 Bug fixes
- TOCTOU on settings —
NepkitSettingsnow re-readssettings.NEPKITon every attribute access;override_settingsandsetting_changedare honoured. TheBS_*_FORMATconstants are re-exported via a module-level__getattr__so directfrom django_nepkit.utils import BS_DATE_FORMATre-reads too. - XSS in
_render_options—id/text/ placeholder values are now HTML-escaped. Fixes a latent reflected/stored XSS sink reachable from?html=trueand theHX-Request: truepaths. format_nepali_currencyprecision loss — switched fromfloattoDecimalend-to-end.Decimal("123456789012345.67")now formats as"Rs. 1,23,45,67,89,01,234.57"instead of truncated float garbage.format_nepali_currencynon-finite rejection —inf/nan/"1e1000"now raiseValueErrorinstead of producing"inf".number_to_nepali_wordsnegative crash — negative numbers now render with the"ऋणात्मक"prefix instead of raisingIndexError.NepaliDatePickerWidget.format_valueEN-mode leak — passing anepalidatein English mode no longer leaks its Python repr ("nepalidate(2081, 1, 15)") into the rendered HTML; unknown value types render as"".NepaliTimeWidget.format_valueEN-mode leak — same fix for time values._parse_language_paramssilent coercion —?ne=banananow falls back to the project default instead of silently returningFalse; withstrict=Trueit raisesValueError._get_primary_paramambiguous fallback — when the URL has multiple non-internal params, the named parameter takes priority and the "first non-internal" fallback is skipped.address-chaining.jschange-event storm — the init path no longer fires syntheticchangeevents, so user-defined change handlers don't run during page load.address-chaining.jsMutationObserver scope — the observer now only triggers init on additions ofform/.nepkit-province-select/.nepkit-district-selectinstead of every DOM mutation.address-chaining.jssilent fetch failure — server errors are now logged viaconsole.errorinstead of swallowed silently.nepali-time-init.jsinvalid-state styling — the.nepkit-time-invalidclass now ships with default CSS (red border + soft red background).nepali-time-init.jsNepali-digit input —०१:००is now normalised to ASCII before regex matching.- Address normalisation fuzzy match —
_find_location_in_tokensnow ranks candidates (exact > substring) so"Pokhara"no longer loses to"Pokhara Metropolitan City"(or vice versa) for the same token. - Exception narrowing —
_try_parse_nepali/try_parse_nepali_timenow catchnepali.exceptions.FormatNotMatchExceptionexplicitly instead of relying on it happening to be aValueError. - Admin
except Exception: pass— replaced with narrowexcept (FieldDoesNotExist, AttributeError)so genuine bugs surface instead of being swallowed. NoReverseMatchswallowed in widgets — the missing-URL case is now logged at WARNING with a hint pointing at the URLconf.- Demo API input validation —
?order=…,?year=…,?month=…,?amount_range=…and?date_range=…all return 400 on bad input (out-of-range month, non-numeric range, unknown order field, …) instead of 500-ing the request. Accept-Languagefallback — the demo's_ne_flagnow honoursAccept-Language: nein addition to?ne=true.
♻️ Refactoring
- Extracted framework-agnostic serialization logic into
django_nepkit.api(the only public serialization surface). NepaliDatePickerWidget._configure_attrsnow chains tosuper().__init__.pyis now safe to import with no extra packages installed, and re-exportsnepkit_settingsfor live access.NepkitSettingsre-readssettings.NEPKITon every access (sooverride_settingsfinally works) and refuses attribute assignment (it's read-only — changesettings.NEPKITinstead).BaseNepaliBSField.format_stris now a@propertyso it re-reads the currentBS_DATE_FORMAT/BS_DATETIME_FORMATsetting at call time.BaseNepaliBSField.pre_saveshared helper factored out; the date / datetime subclasses no longer duplicate the TZ normalization logic._render_optionsescapes its HTML output (fixes latent XSS sink) and now usesformat_html_join.format_nepali_date/format_nepali_datetimeexposed indjango_nepkit.utils(previously onlyformat_nepali_timewas available there).
V.0.2.1 — 2027-02-05
✨ Features
- upgrade nepali package to 1.2.0 and remove hardcoded Koshi Province mapping
♻️ Refactoring
- remove code redundancy and improve maintainability
- extract duplicate view logic into reusable helper functions in views.py
- create constants.py for centralized hardcoded values (Nepali words, placeholders)
- simplify number_to_nepali_words function from 157 to 42 lines
- refactor normalize_address with extracted helper functions
- add lang_utils.py for consistent language parameter handling
- reduce JavaScript duplication in address-chaining.js with helper functions
- move circular import from module level to method scope in models.py
- remove ~160+ lines of redundant code while preserving all logic
V.0.2.0 — 2026-01-31
✨ Features
- implement address normalization
- REST API enhancements
- add Nepali currency field, number to words, and unicode helpers
- add English datepicker support and comprehensive documentation improvements
- implement HTMX support, DRF filters, and professionalized documentation
- implement zero-config address chaining and revamp documentation
- revamp localization support with Devanagari (BS) integration
📚 Documentation
- added showcase
- updated readme
🧹 Other Changes
- fixed workflow
- added todo
- added workflow
- added comprehensive pytest test suite with 67% coverage
- global project refinement, DRY consolidation, and documentation overhaul
V.0.1.0 — 2026-01-29
- Initial release