Features
-
Implemented sub-filter functionality in Django admin #700
IntroducedSubFilterMixinto allow admin filters to be displayed and applied only when a parent filter has specific values. This enhances the admin interface by enabling hierarchical filtering.
The filter rendering system has been updated to group parent filters with their sub-filters, displaying sub-filters vertically below their parents. Client-side JavaScript logic dynamically shows or hides sub-filters based on parent filter selections.
Invalid sub-filter usage, such as providing a sub-filter value when its parent is inactive, will now raiseIncorrectLookupParameters. Misconfigured orphaned sub-filters will be logged as errors and not rendered. -
Add OpenWispPagination class with default values #586
Introduces theOpenWispPaginationclass, inheriting from DRF'sPageNumberPagination. This class provides sensible default values for pagination across OpenWISP modules, configurable via settings.
The default page size is set to 10 and the maximum page size to 100. These can be overridden byOPENWISP\_API\_DEFAULT\_PAGE\_SIZEandOPENWISP\_API\_MAX\_PAGE\_SIZErespectively. Views can also set apagination\_page\_sizeattribute to override the default for specific endpoints. -
Added changelog entry bot #523
-
Automate assigning/unassigning issues #571
Added auto-assignment bot with issue assignment, management of stale PR, reassignment on PR reopen and shared helpers in utils.py. -
Added CI build failure bot #524
When a CI workflow fails, the bot examines the failure logs and repository context with AI to offer specific guidance for fixing QA check issues, test failures and other common bugs. -
Added reusable backport workflow #501
Automates cherry-picking fixes to stable branches via[backport X.Y]in commit messages or/backport X.Ycomments, with conflict notification. -
Standardized commit messages using commitizen #110
Commitizen has been integrated in openwisp-utils to standardize how commit messages are written across the project. It introduces an interactive commit workflow that guides contributors to use the correct OpenWISP commit format, ensures commit titles are properly structured, and enforces the presence of an issue reference. The commit message footer is generated automatically using the provided issue number, improving consistency and making commits easier to review and track. -
Releaser: added support for non-python packages #522
Changes
Backward-incompatible changes
- Removed deprecated
UUIDAdminclass #328
The deprecatedUUIDAdminclass has been removed. For equivalent functionality, useCopyableFieldsAdminwithcopyable\_fields = ('uuid',).
Other changes
-
Included commit bodies in releaser changelog
-
Allowed cascade deletions in
ReadOnlyAdmin
ReadOnlyAdmin.has\_delete\_permissionpreviously returnedFalseunconditionally, which blocked cascade deletions from parent models (likeOrganization).
Addedopenwisp\_utils.admin.BlockDeleteAllowCascadeMixinto allow reusability of this logic in other OpenWISP modules. -
Excluded local python venv dirs from QA checks #720
-
Made menu item registration idempotent #641
Previously, callingregister\_menu\_grouporregister\_menu\_subitemtwice with the same configuration at the same position would always raise anImproperlyConfiguredexception. This behavior prevented re-registration, even when the same application was re-initializing its menu items during testing.
This change modifies these functions to check if the configuration being registered is identical to the one already present at that position. If the configurations match, the function now logs an informational message and skips the re-registration instead of raising an error. This makes the menu item registration process idempotent, improving testability and handling of repeated app initializations. -
Releaser: defined a generic package type to use as fallback
The logic which detected OpenWrt packages has been generalized so that any file which doesn't fall under well defined categories like "python package", "npm package", "ansible role", etc., can fall under the "generic package" type, as long as a VERSION file is defined in the top level directory of the repository, the releaser tool will be able to deal with it, regardless of the tech stack used. -
Made changelog bot model configurable and quota-resilient
The changelog bot kept failing with Gemini free-tier quota errors (RequestsPerDayPerProjectPerModel, 20/day) and marked the workflow as failed, while the CI failure bot stayed green because it swallows the same error. The changelog bot also had no way to switch models and could spend up to three requests per pull request.
ForwardGEMINI\_MODELthrough the action and reusable workflow so a single variable controls both bots, harden model resolution so an empty value falls back to the default, lower the generation retries from three to two, and exit cleanly on quota errors so the workflow no longer turns red on exhaustion.
Also document theGEMINI\_MODELvariable for both bots. -
SeleniumTestMixin now requires two successful retries after an initial failure
-
Added default
uuidmethod toCopyableFieldsAdmin#328
CopyableFieldsAdminnow ships with a defaultuuid()method that returnsobj.pkand hasshort\_descriptionset to'UUID'. This allows subclasses to usecopyable\_fields = ('uuid',)without defining their ownuuidmethod when their model uses a UUID primary key.
Theuuidfield is not automatically added tocopyable\_fields, that's still the developer's explicit decision. -
Releaser: removed chatGPT integration #645
-
Releaser: automated branch selection in changelog porting step #646
Dependencies
-
Bumped
blackto 26.5.1 (>=25.1,<26.6)
Updates the requirements on black_ to permit the latest version. - Release notes_ - Changelog_ - Commits_ -
Bumped
celeryto 5.6.1 (~=5.6.1)
Updates the requirements on celery_ to permit the latest version. - Release notes_ - Changelog_ -
Bumped
djangorestframeworkto 3.17.1 (~=3.17.1)
Updates the requirements on djangorestframework_ to permit the latest version. - Release notes_ - Commits_ -
Bumped
git-cliffto 2.13.1 (~=2.13.1)
Updates the requirements on git-cliff_ to permit the latest version. - Release notes_ - Changelog_ - Commits_ -
Bumped
isortto 8.0.1 (>=6.0.1,<8.1.0)
Updates the requirements on isort_ to permit the latest version. - Release notes_ - Changelog_ - Commits_ -
Bumped
pytest-asyncioto 1.4.0 (>=1.3.0,<1.5.0)
Updates the requirements on pytest-asyncio_ to permit the latest version. - Release notes_ - Commits_ -
Bumped
seleniumto 4.46.0 (>=4.32,<4.47)
Updates the requirements on selenium_ to permit the latest version. - Release notes_ - Commits_ -
Bumped
tblibto 3.2.2 (~=3.2.2)
Updates the requirements on tblib_ to permit the latest version. - Release notes_ - Changelog_ - Commits_ -
Bumped
django-filterto 26.1 (>=25.1,<27.0)
Updates the requirements on django-filter_ to permit the latest version. - Release notes_ - Changelog_
- Commits_ -
Bumped
coverageto 7.15.2 (>=7.10.0,<7.16.0)
Updates the requirements on coverage_ to permit the latest version. - Release notes_ - Changelog_ - Commits_ -
Bumped
docstrfmtto 2.2.0 (>=2.0.0,<2.3.0)
Updates the requirements on docstrfmt_ to permit the latest version. - Release notes_ - Changelog_ - Commits_ -
Bumped
google-genaito 2.7.0 (>=1.62.0,<3.0.0)
Updates the requirements on google-genai_ to permit the latest version. - Release notes_ - Changelog_ - Commits_ -
Bumped
django-minify-compress-staticfilesto 1.1.1
See Release Notes: https://github.com/openwisp/django-minify-compress-staticfiles/releases/tag/1.1.1 -
Bumped
pytest-djangoto 4.12.0 (>=4.10,<4.13)
Updates the requirements on pytest-django_ to permit the latest version. - Release notes_ - Changelog_
- Commits_
Bugfixes
-
Reload DRF settings after configuring defaults
Bug:ApiAppConfig.configure\_rest\_framework\_defaultsupdated Django'ssettings.REST\_FRAMEWORK, but DRF'sapi\_settingshad already loaded its own copy of the configuration. As a result, changes made by apps initialized afterrest\_frameworkwere not reflected in the settings actually used by DRF.
Fix: Reloadrest\_framework.settings.api\_settingsafter updatingsettings.REST\_FRAMEWORKso DRF uses the latest configuration. -
Prevented capture decorators from polluting exceptions
CaptureOutput previously tried injecting streams and retried any TypeError. A real failure in a no-argument decorated test retained the expected signature mismatch as exception context, obscuring the regression traceback.
The decorator now selects the valid call signature before executing the test, while preserving support for explicit captured streams, variadic arguments, and stackedmock.patchdecorators. -
Prevented FallbackMixin from generating spurious migrations #1231
-
Collect Firefox console logs via WebDriver BiDi #696
Firefox >= 135 no longer loads the Manifest v2 console-capture extension, and Manifest v3 content scripts are not granted host permissions for temporarily installed add-ons, so the content script never runs. As a resultget\_browser\_logs()returnedundefined(which translated toNonein Python) instead of the captured logs on modern Firefox versions, which in turn broke CI builds.
The extension was replaced with WebDriver BiDi: a console message handler records every console entry, including those emitted during page load, and the log buffer is reset on each navigation to preserve the previous per-page semantics.
This fixes console capture for every OpenWISP module that relies onSeleniumTestMixinwithout changing its public API. -
Excluded
node\_modulesdir and other hidden directories from the ReStructuredText QA check -
Fixed
ValidatedModelSerializervalidation of PUT/PATCH and relationships #633
UpdatedValidatedModelSerializer.validate()to: -
Use
copy()for existing instances to avoid mutating the original. - Skip reverse relations (ForeignObjectRel) duringsetattr. - Skip nested relationships. - Convert DjangoValidationErrorto DRFValidationErrorso errors are properly serialized in API responses and picklable in the parallel test runner. -
Triggered changelog bot for backward incompatible changes
Accept[change!]entries in the changelog bot trigger and validation so backward incompatible PRs receive generated changelog suggestions. -
Fixed double encoding of device model labels in dashboard #651
Fixed the double-encoding issue in admin dashboard charts where device models with special characters (like &) generated malformed URLs. -
Fixed broken skipped Selenium tests in Django parallel runner #619
-
Fixed gemini call
-
Switched to django-minify-compress-staticfiles #565
Replaced the unmaintained django-compress-staticfiles with the new django-minify-compress-staticfiles package for static file minification and compression. -
Releaser: perform
git pull --tagsbefore changelog generation