From 3ca2a18a3fb99e9256ea9044c2411fbda4a7add2 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 22 Oct 2025 15:29:26 -0400 Subject: [PATCH] Introduce AdminModel base class to provide enhanced UI functionality for Owner --- netbox/netbox/models/__init__.py | 27 +++++++++++++++++++++++++-- netbox/users/models/owners.py | 9 +++------ netbox/utilities/querydict.py | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/netbox/netbox/models/__init__.py b/netbox/netbox/models/__init__.py index e6f1ecfd4..1e2846748 100644 --- a/netbox/netbox/models/__init__.py +++ b/netbox/netbox/models/__init__.py @@ -11,10 +11,9 @@ from netbox.models.features import * from netbox.models.mixins import OwnerMixin from utilities.mptt import TreeManager from utilities.querysets import RestrictedQuerySet -from utilities.views import get_viewname - __all__ = ( + 'AdminModel', 'ChangeLoggedModel', 'NestedGroupModel', 'NetBoxModel', @@ -44,6 +43,7 @@ class NetBoxFeatureSet( return f'{settings.STATIC_URL}docs/models/{self._meta.app_label}/{self._meta.model_name}/' def get_absolute_url(self): + from utilities.views import get_viewname return reverse(get_viewname(self), args=[self.pk]) @@ -222,3 +222,26 @@ class OrganizationalModel(OwnerMixin, NetBoxModel): def __str__(self): return self.name + + +class AdminModel( + BookmarksMixin, + CloningMixin, + CustomLinksMixin, + CustomValidationMixin, + EventRulesMixin, + ExportTemplatesMixin, + NotificationsMixin, + BaseModel, +): + """ + A model which represents an administrative resource. + """ + description = models.CharField( + verbose_name=_('description'), + max_length=200, + blank=True + ) + + class Meta: + abstract = True diff --git a/netbox/users/models/owners.py b/netbox/users/models/owners.py index 6765d3034..bf24e43f8 100644 --- a/netbox/users/models/owners.py +++ b/netbox/users/models/owners.py @@ -2,6 +2,7 @@ from django.db import models from django.urls import reverse from django.utils.translation import gettext_lazy as _ +from netbox.models import AdminModel from utilities.querysets import RestrictedQuerySet __all__ = ( @@ -9,17 +10,12 @@ __all__ = ( ) -class Owner(models.Model): +class Owner(AdminModel): name = models.CharField( verbose_name=_('name'), max_length=150, unique=True, ) - description = models.CharField( - verbose_name=_('description'), - max_length=200, - blank=True - ) groups = models.ManyToManyField( to='users.Group', verbose_name=_('groups'), @@ -36,6 +32,7 @@ class Owner(models.Model): ) objects = RestrictedQuerySet.as_manager() + clone_fields = ('groups', 'users') class Meta: ordering = ('name',) diff --git a/netbox/utilities/querydict.py b/netbox/utilities/querydict.py index 73d40bfc4..17a0c8c2b 100644 --- a/netbox/utilities/querydict.py +++ b/netbox/utilities/querydict.py @@ -2,7 +2,7 @@ from urllib.parse import urlencode from django.http import QueryDict from django.utils.datastructures import MultiValueDict -from netbox.models import CloningMixin +from netbox.models.features import CloningMixin __all__ = ( 'dict_to_querydict',