Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,65 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.5.0] - 2026-08-24

### Changed

- **netbox-custom-objects compatibility floor raised to 0.6.0**
([release notes](https://github.com/netboxlabs/netbox-custom-objects/releases/tag/v0.6.0)).
The `PluginConfig.ready()` probe now checks for
`CustomObjectFieldTypeChoices.TYPE_COORDINATES` (added in 0.6.0) and
raises `ImproperlyConfigured` pointing at
`pip install -U 'netbox-custom-objects>=0.6.0'`. 0.5.x installs must
stay on plugin 2.4.1. NetBox floors are unchanged (4.5.2 – 4.6.99,
matching upstream 0.6.x).
- **Regenerated the `customobject.html` template override from the
0.6.0 stock template.** The 2.4.x copy was based on 0.5.x and silently
dropped upstream features when run against 0.6.0. The refresh restores:
Contacts tab, Config Context tab (shown when the type has
`config_context_enabled`), owner display in the page header,
`coordinates` field rendering with a Map button, the polymorphic
M2M "Type" column in many-field cards, and the switch to the
`{% customfield_value %}` builtin tag. Our two insertions (the
`custom_object_tab_tags` load and `{% plugin_extra_tabs object %}`
between Contacts and Journal) are the only deltas from stock, and the
file intentionally keeps upstream formatting so future refreshes are a
plain `diff` against the new stock template.
- **Typed-tab filter sidebar now reuses upstream's
`build_filterset_form_class()`** (`netbox_custom_objects.dynamic_forms`)
instead of a local replica — the same builder `CustomObjectListView`
uses, so the sidebar automatically gains the 0.6.0 owner filter.

### Added

- **Owner column and filter in the combined tab.** New "Owner" column
(sortable, hideable via Configure Table) showing the 0.6.0 ownership
field, plus an owner dropdown filter next to the tag filter. Owner rows
are fetched with `select_related("owner")` — no extra queries. Note:
the text search (`q`) still matches object/type/field only, not owner
names.

### Fixed

- **`TemplateDoesNotExist` (HTTP 500) on tab pages of models without a
per-model detail template** — e.g. `/ipam/vrfs/<pk>/custom-objects-<slug>/`
crashed with `TemplateDoesNotExist: ipam/vrf.html`, likewise MAC
addresses (`dcim/macaddress.html`) and any other model NetBox renders
via the generic detail view. `_get_base_template()` built
`"{app}/{model}.html"` unconditionally; it now delegates to NetBox's
`utilities.views.get_default_template()`, which falls back to
`generic/object.html` — the same resolution NetBox's own
Journal/Changelog tabs use. Affected both combined and typed tabs.
- **Polymorphic filter fields missing from the typed-tab sidebar.** The
local filter-form replica assigned the dict returned by polymorphic
`get_filterform_field()` (one form field per allowed target type) to a
single form attribute, so those filters never rendered. Fixed by the
switch to upstream's `build_filterset_form_class()`, which expands the
dict correctly.
- **Field column sort link broken in the combined tab** — a mismatched
template brace (`{{ sort_headers.field.url %}`) rendered the URL
expression as literal text instead of the sort link.

## [2.4.1] - 2026-05-25

### Changed
Expand Down
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,30 @@ Two tab modes are available:
## Requirements

- NetBox 4.5.2 – 4.6.99
- `netbox_custom_objects` plugin **≥ 0.5.1** installed and configured
(0.5.0 had an upstream Delete bug fixed in 0.5.1; see [Known Issues](#known-issues))
- `netbox_custom_objects` plugin **≥ 0.6.0** installed and configured
(0.5.x installs must stay on plugin 2.4.1)

## Compatibility

| Plugin version | NetBox version | `netbox_custom_objects` version |
|----------------|----------------|------------------------------------------------------------------------|
| 2.5.x | 4.5.2+ / 4.6.x | **≥ 0.6.0 required** |
| 2.4.x | 4.5.2+ / 4.6.x | **≥ 0.5.1 required** |
| 2.3.x | 4.5.4+ / 4.6.x | ≥ 0.4.6 (≥ 0.5.0 on 4.6) |
| 2.2.x | 4.5.4+ / 4.6.x | ≥ 0.4.6 (≥ 0.5.0 on 4.6) |
| 2.1.x | 4.5.4+ | ≥ 0.4.6 |
| 2.0.x | 4.5.x | ≥ 0.4.6 |
| 1.0.x | 4.5.x | ≥ 0.4.4 |

Plugin 2.4.x **enforces** the 0.5.1 minimum at startup: `PluginConfig.ready()`
probes for the upstream `is_polymorphic` model field (introduced in 0.5.0)
Plugin 2.5.x **enforces** the 0.6.0 minimum at startup: `PluginConfig.ready()`
probes for the upstream `coordinates` field type (introduced in 0.6.0)
and raises `ImproperlyConfigured` with an upgrade message pointing at
`>=0.5.1` if the installed upstream is older. The check is behaviour-based
(looks for the field, not a version string) so it stays correct across forks
and pre-release tags; the message advances to 0.5.1 because 2.4.x assumes
the bug fixes shipped in that release.
`>=0.6.0` if the installed upstream is older. The check is behaviour-based
(looks for the feature, not a version string) so it stays correct across forks
and pre-release tags. The hard floor exists because the plugin ships a copy of
the 0.6.0 `customobject.html` detail template (Contacts and Config Context
tabs, owner display, coordinates rendering), which reverses URLs that do not
exist on 0.5.x.

## Installation

Expand Down
27 changes: 14 additions & 13 deletions netbox_custom_objects_tab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,24 @@ class NetBoxCustomObjectsTabConfig(PluginConfig):
def ready(self):
super().ready()

# Hard gate: require netbox-custom-objects >= 0.5.0. We probe behaviour
# (the `is_polymorphic` model field added in 0.5.0) rather than parsing
# a version string, because forks and pre-release tags can carry any
# version label but either have or lack the field we actually use.
# Hard gate: require netbox-custom-objects >= 0.6.0. We probe behaviour
# (the `coordinates` field type added in 0.6.0) rather than parsing a
# version string, because forks and pre-release tags can carry any
# version label but either have or lack the feature we actually use.
# Our customobject.html override is a copy of the 0.6.0 stock template
# (Contacts/Config Context tabs, coordinates rendering, owner header),
# which reverses URLs that don't exist on 0.5.x — hence the hard floor.
# Raising ImproperlyConfigured here aborts NetBox startup with a clean,
# named error in the logs — preferable to letting a half-loaded plugin
# ImportError mid-request.
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
from netbox_custom_objects.models import CustomObjectTypeField
# NoReverseMatch mid-request.
from django.core.exceptions import ImproperlyConfigured
from netbox_custom_objects.choices import CustomObjectFieldTypeChoices

try:
CustomObjectTypeField._meta.get_field("is_polymorphic")
except FieldDoesNotExist as exc:
if not hasattr(CustomObjectFieldTypeChoices, "TYPE_COORDINATES"):
raise ImproperlyConfigured(
"netbox-custom-objects-tab 2.4+ requires netbox-custom-objects>=0.5.1. "
"Upgrade with: pip install -U 'netbox-custom-objects>=0.5.1'"
) from exc
"netbox-custom-objects-tab 2.5+ requires netbox-custom-objects>=0.6.0. "
"Upgrade with: pip install -U 'netbox-custom-objects>=0.6.0'"
)

from . import template_override, views

Expand Down
Loading
Loading