Plugin Version
v0.6.0
Proposed functionality
Add support for compound (multi-field) uniqueness constraints at the Custom Object Type level — exposed via the UI, the REST API, and the portable schema — backed by a real Postgres UniqueConstraint on the generated table. Today, CustomObjectTypeField only supports a scalar per-field unique boolean; there is no CustomObjectTypeConstraint / unique_together concept on CustomObjectType, and the portable schema (cot_schema_v1.json) has no way to express a multi-column constraint.
In rough order of frequency of use across surveyed plugins, the design should cover:
- Plain multi-field uniqueness (
UniqueConstraint(fields=[...]) / unique_together) — needed by every surveyed plugin.
- Uniqueness over a functional expression, e.g. case-insensitive uniqueness via
UniqueConstraint(Lower('name')) — used by netbox-lifecycle (SupportSKU, SupportContract, License, Vendor).
- Uniqueness spanning both halves of a polymorphic/GFK-style reference (
object_type + object_id) — used by netbox-lifecycle's HardwareLifecycle, netbox-attachments' Assignment, and netbox-acls' ACLAssignment.
Use case
This is the single most common structural blocker preventing NetBox plugins from being modeled with Custom Objects instead of a full plugin. Of 9 model-defining plugins surveyed (netbox-inventory, netbox-lifecycle, netbox-physical-geometry, netbox-documents, netbox-attachments, netbox-acls, netbox-contract, netbox-public-clouds, slurpit_netbox), 8 rely on compound uniqueness at least once — for example:
CloudAccount(cloud_platform, account_id) — netbox-public-clouds
Asset(device_type, serial), Purchase(supplier, name) — netbox-inventory
ACLRule(access_list, sequence) — netbox-acls
Floorplan(location, name) — netbox-physical-geometry
Without this, none of these plugins' data models can be fully replaced by Custom Objects, which directly undercuts the core goal of Custom Objects: reducing the surface area of data-model extensions that require a full plugin.
External dependencies
None. Implementable with Django's existing UniqueConstraint support and the schema executor's existing raw-DDL machinery (connection.schema_editor()).
Plugin Version
v0.6.0
Proposed functionality
Add support for compound (multi-field) uniqueness constraints at the Custom Object Type level — exposed via the UI, the REST API, and the portable schema — backed by a real Postgres
UniqueConstrainton the generated table. Today,CustomObjectTypeFieldonly supports a scalar per-fielduniqueboolean; there is noCustomObjectTypeConstraint/unique_togetherconcept onCustomObjectType, and the portable schema (cot_schema_v1.json) has no way to express a multi-column constraint.In rough order of frequency of use across surveyed plugins, the design should cover:
UniqueConstraint(fields=[...])/unique_together) — needed by every surveyed plugin.UniqueConstraint(Lower('name'))— used by netbox-lifecycle (SupportSKU,SupportContract,License,Vendor).object_type+object_id) — used by netbox-lifecycle'sHardwareLifecycle, netbox-attachments'Assignment, and netbox-acls'ACLAssignment.Use case
This is the single most common structural blocker preventing NetBox plugins from being modeled with Custom Objects instead of a full plugin. Of 9 model-defining plugins surveyed (netbox-inventory, netbox-lifecycle, netbox-physical-geometry, netbox-documents, netbox-attachments, netbox-acls, netbox-contract, netbox-public-clouds, slurpit_netbox), 8 rely on compound uniqueness at least once — for example:
CloudAccount(cloud_platform, account_id)— netbox-public-cloudsAsset(device_type, serial),Purchase(supplier, name)— netbox-inventoryACLRule(access_list, sequence)— netbox-aclsFloorplan(location, name)— netbox-physical-geometryWithout this, none of these plugins' data models can be fully replaced by Custom Objects, which directly undercuts the core goal of Custom Objects: reducing the surface area of data-model extensions that require a full plugin.
External dependencies
None. Implementable with Django's existing
UniqueConstraintsupport and the schema executor's existing raw-DDL machinery (connection.schema_editor()).