1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Merge pull request #10313 from netbox-community/10304-customfield-clone

Fixes #10304: Enable cloning for custom fields & custom links
This commit is contained in:
Jeremy Stretch
2022-09-09 17:04:01 -04:00
committed by GitHub
4 changed files with 45 additions and 27 deletions

View File

@ -14,7 +14,7 @@ from django.utils.safestring import mark_safe
from extras.choices import *
from extras.utils import FeatureQuery
from netbox.models import ChangeLoggedModel
from netbox.models.features import ExportTemplatesMixin, WebhooksMixin
from netbox.models.features import CloningMixin, ExportTemplatesMixin, WebhooksMixin
from utilities import filters
from utilities.forms import (
CSVChoiceField, CSVMultipleChoiceField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
@ -41,7 +41,7 @@ class CustomFieldManager(models.Manager.from_queryset(RestrictedQuerySet)):
return self.get_queryset().filter(content_types=content_type)
class CustomField(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
class CustomField(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
content_types = models.ManyToManyField(
to=ContentType,
related_name='custom_fields',
@ -143,8 +143,14 @@ class CustomField(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
verbose_name='UI visibility',
help_text='Specifies the visibility of custom field in the UI'
)
objects = CustomFieldManager()
clone_fields = (
'content_types', 'type', 'object_type', 'group_name', 'description', 'required', 'filter_logic', 'default',
'weight', 'validation_minimum', 'validation_maximum', 'validation_regex', 'choices', 'ui_visibility',
)
class Meta:
ordering = ['group_name', 'weight', 'name']

View File

@ -21,7 +21,7 @@ from extras.conditions import ConditionSet
from extras.utils import FeatureQuery, image_upload
from netbox.models import ChangeLoggedModel
from netbox.models.features import (
CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, JobResultsMixin, TagsMixin, WebhooksMixin,
CloningMixin, CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, JobResultsMixin, TagsMixin, WebhooksMixin,
)
from utilities.querysets import RestrictedQuerySet
from utilities.utils import render_jinja2
@ -187,7 +187,7 @@ class Webhook(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
return render_jinja2(self.payload_url, context)
class CustomLink(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
class CustomLink(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
"""
A custom link to an external representation of a NetBox object. The link text and URL fields accept Jinja2 template
code to be rendered with an object as context.
@ -230,6 +230,10 @@ class CustomLink(ExportTemplatesMixin, WebhooksMixin, ChangeLoggedModel):
help_text="Force link to open in a new window"
)
clone_fields = (
'content_type', 'enabled', 'weight', 'group_name', 'button_class', 'new_window',
)
class Meta:
ordering = ['group_name', 'weight', 'name']

View File

@ -2,7 +2,6 @@ from django.core.validators import ValidationError
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
from extras.utils import is_taggable
from utilities.mptt import TreeManager
from utilities.querysets import RestrictedQuerySet
from netbox.models.features import *
@ -32,7 +31,7 @@ class NetBoxFeatureSet(
def get_prerequisite_models(cls):
"""
Return a list of model types that are required to create this model or empty list if none. This is used for
showing prequisite warnings in the UI on the list and detail views.
showing prerequisite warnings in the UI on the list and detail views.
"""
return []
@ -52,7 +51,7 @@ class ChangeLoggedModel(ChangeLoggingMixin, CustomValidationMixin, models.Model)
abstract = True
class NetBoxModel(NetBoxFeatureSet, models.Model):
class NetBoxModel(CloningMixin, NetBoxFeatureSet, models.Model):
"""
Primary models represent real objects within the infrastructure being modeled.
"""
@ -61,25 +60,6 @@ class NetBoxModel(NetBoxFeatureSet, models.Model):
class Meta:
abstract = True
def clone(self):
"""
Return a dictionary of attributes suitable for creating a copy of the current instance. This is used for pre-
populating an object creation form in the UI.
"""
attrs = {}
for field_name in getattr(self, 'clone_fields', []):
field = self._meta.get_field(field_name)
field_value = field.value_from_object(self)
if field_value not in (None, ''):
attrs[field_name] = field_value
# Include tags (if applicable)
if is_taggable(self):
attrs['tags'] = [tag.pk for tag in self.tags.all()]
return attrs
class NestedGroupModel(NetBoxFeatureSet, MPTTModel):
"""

View File

@ -10,12 +10,13 @@ from django.db import models
from taggit.managers import TaggableManager
from extras.choices import CustomFieldVisibilityChoices, ObjectChangeActionChoices
from extras.utils import register_features
from extras.utils import is_taggable, register_features
from netbox.signals import post_clean
from utilities.utils import serialize_object
__all__ = (
'ChangeLoggingMixin',
'CloningMixin',
'CustomFieldsMixin',
'CustomLinksMixin',
'CustomValidationMixin',
@ -82,6 +83,33 @@ class ChangeLoggingMixin(models.Model):
return objectchange
class CloningMixin(models.Model):
"""
Provides the clone() method used to prepare a copy of existing objects.
"""
class Meta:
abstract = True
def clone(self):
"""
Return a dictionary of attributes suitable for creating a copy of the current instance. This is used for pre-
populating an object creation form in the UI.
"""
attrs = {}
for field_name in getattr(self, 'clone_fields', []):
field = self._meta.get_field(field_name)
field_value = field.value_from_object(self)
if field_value not in (None, ''):
attrs[field_name] = field_value
# Include tags (if applicable)
if is_taggable(self):
attrs['tags'] = [tag.pk for tag in self.tags.all()]
return attrs
class CustomFieldsMixin(models.Model):
"""
Enables support for custom fields.