mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 17:08:41 -06:00
Add custom field support to ComponentCreateForm
This commit is contained in:
parent
d6ee4d58ba
commit
9db492eb07
@ -12,8 +12,8 @@ from timezone_field import TimeZoneFormField
|
|||||||
|
|
||||||
from circuits.models import Circuit, CircuitTermination, Provider
|
from circuits.models import Circuit, CircuitTermination, Provider
|
||||||
from extras.forms import (
|
from extras.forms import (
|
||||||
AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldModelCSVForm, CustomFieldFilterForm, CustomFieldModelForm,
|
AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldModelCSVForm, CustomFieldFilterForm,
|
||||||
LocalConfigContextFilterForm,
|
CustomFieldModelForm, LocalConfigContextFilterForm,
|
||||||
)
|
)
|
||||||
from extras.models import Tag
|
from extras.models import Tag
|
||||||
from ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN
|
from ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN
|
||||||
@ -22,10 +22,9 @@ from tenancy.forms import TenancyFilterForm, TenancyForm
|
|||||||
from tenancy.models import Tenant, TenantGroup
|
from tenancy.models import Tenant, TenantGroup
|
||||||
from utilities.forms import (
|
from utilities.forms import (
|
||||||
APISelect, APISelectMultiple, add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
|
APISelect, APISelectMultiple, add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
|
||||||
ColorSelect, CommentField, CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVModelForm,
|
ColorSelect, CommentField, CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, DynamicModelChoiceField,
|
||||||
DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model, JSONField,
|
DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model, JSONField, NumericArrayField, SelectWithPK,
|
||||||
NumericArrayField, SelectWithPK, SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField,
|
SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
|
||||||
BOOLEAN_WITH_BLANK_CHOICES,
|
|
||||||
)
|
)
|
||||||
from virtualization.models import Cluster, ClusterGroup
|
from virtualization.models import Cluster, ClusterGroup
|
||||||
from .choices import *
|
from .choices import *
|
||||||
@ -119,7 +118,7 @@ class InterfaceCommonForm(forms.Form):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class ComponentForm(BootstrapMixin, forms.Form):
|
class ComponentForm(forms.Form):
|
||||||
"""
|
"""
|
||||||
Subclass this form when facilitating the creation of one or more device component or component templates based on
|
Subclass this form when facilitating the creation of one or more device component or component templates based on
|
||||||
a name pattern.
|
a name pattern.
|
||||||
@ -1073,7 +1072,7 @@ class DeviceTypeFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
|||||||
# Device component templates
|
# Device component templates
|
||||||
#
|
#
|
||||||
|
|
||||||
class ComponentTemplateCreateForm(ComponentForm):
|
class ComponentTemplateCreateForm(BootstrapMixin, ComponentForm):
|
||||||
"""
|
"""
|
||||||
Base form for the creation of device component templates (subclassed from ComponentTemplateModel).
|
Base form for the creation of device component templates (subclassed from ComponentTemplateModel).
|
||||||
"""
|
"""
|
||||||
@ -2270,11 +2269,10 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
|||||||
# Device components
|
# Device components
|
||||||
#
|
#
|
||||||
|
|
||||||
class ComponentCreateForm(ComponentForm):
|
class ComponentCreateForm(BootstrapMixin, CustomFieldForm, ComponentForm):
|
||||||
"""
|
"""
|
||||||
Base form for the creation of device components (models subclassed from ComponentModel).
|
Base form for the creation of device components (models subclassed from ComponentModel).
|
||||||
"""
|
"""
|
||||||
# TODO: Enable custom field support
|
|
||||||
device = DynamicModelChoiceField(
|
device = DynamicModelChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
display_field='display_name'
|
display_field='display_name'
|
||||||
@ -2289,7 +2287,7 @@ class ComponentCreateForm(ComponentForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DeviceBulkAddComponentForm(ComponentForm):
|
class DeviceBulkAddComponentForm(BootstrapMixin, ComponentForm):
|
||||||
# TODO: Enable custom field support
|
# TODO: Enable custom field support
|
||||||
pk = forms.ModelMultipleChoiceField(
|
pk = forms.ModelMultipleChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
@ -2337,6 +2335,7 @@ class ConsolePortForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class ConsolePortCreateForm(ComponentCreateForm):
|
class ConsolePortCreateForm(ComponentCreateForm):
|
||||||
|
model = ConsolePort
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=add_blank_choice(ConsolePortTypeChoices),
|
choices=add_blank_choice(ConsolePortTypeChoices),
|
||||||
required=False,
|
required=False,
|
||||||
@ -2415,6 +2414,7 @@ class ConsoleServerPortForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class ConsoleServerPortCreateForm(ComponentCreateForm):
|
class ConsoleServerPortCreateForm(ComponentCreateForm):
|
||||||
|
model = ConsoleServerPort
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=add_blank_choice(ConsolePortTypeChoices),
|
choices=add_blank_choice(ConsolePortTypeChoices),
|
||||||
required=False,
|
required=False,
|
||||||
@ -2493,6 +2493,7 @@ class PowerPortForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class PowerPortCreateForm(ComponentCreateForm):
|
class PowerPortCreateForm(ComponentCreateForm):
|
||||||
|
model = PowerPort
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=add_blank_choice(PowerPortTypeChoices),
|
choices=add_blank_choice(PowerPortTypeChoices),
|
||||||
required=False,
|
required=False,
|
||||||
@ -2596,6 +2597,7 @@ class PowerOutletForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class PowerOutletCreateForm(ComponentCreateForm):
|
class PowerOutletCreateForm(ComponentCreateForm):
|
||||||
|
model = PowerOutlet
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=add_blank_choice(PowerOutletTypeChoices),
|
choices=add_blank_choice(PowerOutletTypeChoices),
|
||||||
required=False,
|
required=False,
|
||||||
@ -2808,6 +2810,7 @@ class InterfaceForm(BootstrapMixin, InterfaceCommonForm, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class InterfaceCreateForm(ComponentCreateForm, InterfaceCommonForm):
|
class InterfaceCreateForm(ComponentCreateForm, InterfaceCommonForm):
|
||||||
|
model = Interface
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=InterfaceTypeChoices,
|
choices=InterfaceTypeChoices,
|
||||||
widget=StaticSelect2(),
|
widget=StaticSelect2(),
|
||||||
@ -3089,6 +3092,7 @@ class FrontPortForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
# TODO: Merge with FrontPortTemplateCreateForm to remove duplicate logic
|
# TODO: Merge with FrontPortTemplateCreateForm to remove duplicate logic
|
||||||
class FrontPortCreateForm(ComponentCreateForm):
|
class FrontPortCreateForm(ComponentCreateForm):
|
||||||
|
model = FrontPort
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=PortTypeChoices,
|
choices=PortTypeChoices,
|
||||||
widget=StaticSelect2(),
|
widget=StaticSelect2(),
|
||||||
@ -3247,6 +3251,7 @@ class RearPortForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class RearPortCreateForm(ComponentCreateForm):
|
class RearPortCreateForm(ComponentCreateForm):
|
||||||
|
model = RearPort
|
||||||
type = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=PortTypeChoices,
|
choices=PortTypeChoices,
|
||||||
widget=StaticSelect2(),
|
widget=StaticSelect2(),
|
||||||
@ -3326,6 +3331,7 @@ class DeviceBayForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class DeviceBayCreateForm(ComponentCreateForm):
|
class DeviceBayCreateForm(ComponentCreateForm):
|
||||||
|
model = DeviceBay
|
||||||
field_order = ('device', 'name_pattern', 'label_pattern', 'description', 'tags')
|
field_order = ('device', 'name_pattern', 'label_pattern', 'description', 'tags')
|
||||||
|
|
||||||
|
|
||||||
@ -3449,6 +3455,7 @@ class InventoryItemForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class InventoryItemCreateForm(ComponentCreateForm):
|
class InventoryItemCreateForm(ComponentCreateForm):
|
||||||
|
model = InventoryItem
|
||||||
manufacturer = DynamicModelChoiceField(
|
manufacturer = DynamicModelChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=False
|
required=False
|
||||||
|
@ -7,8 +7,8 @@ from dcim.models import DeviceRole, Platform, Region, Site
|
|||||||
from tenancy.models import Tenant, TenantGroup
|
from tenancy.models import Tenant, TenantGroup
|
||||||
from utilities.forms import (
|
from utilities.forms import (
|
||||||
add_blank_choice, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ColorSelect,
|
add_blank_choice, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ColorSelect,
|
||||||
ContentTypeSelect, CSVModelForm, DateTimePicker, DynamicModelMultipleChoiceField, JSONField, SlugField,
|
CSVModelForm, DateTimePicker, DynamicModelMultipleChoiceField, JSONField, SlugField, StaticSelect2,
|
||||||
StaticSelect2, BOOLEAN_WITH_BLANK_CHOICES,
|
BOOLEAN_WITH_BLANK_CHOICES,
|
||||||
)
|
)
|
||||||
from virtualization.models import Cluster, ClusterGroup
|
from virtualization.models import Cluster, ClusterGroup
|
||||||
from .choices import *
|
from .choices import *
|
||||||
@ -19,8 +19,33 @@ from .models import ConfigContext, CustomField, ImageAttachment, ObjectChange, T
|
|||||||
# Custom fields
|
# Custom fields
|
||||||
#
|
#
|
||||||
|
|
||||||
class CustomFieldModelForm(forms.ModelForm):
|
class CustomFieldForm(forms.Form):
|
||||||
|
"""
|
||||||
|
Extend Form to include custom field support.
|
||||||
|
"""
|
||||||
|
model = None
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if self.model is None:
|
||||||
|
raise NotImplementedError("CustomFieldForm must specify a model class.")
|
||||||
|
self.custom_fields = []
|
||||||
|
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
# Append relevant custom fields to the form instance
|
||||||
|
obj_type = ContentType.objects.get_for_model(self.model)
|
||||||
|
for cf in CustomField.objects.filter(content_types=obj_type):
|
||||||
|
field_name = 'cf_{}'.format(cf.name)
|
||||||
|
self.fields[field_name] = cf.to_form_field()
|
||||||
|
|
||||||
|
# Annotate the field in the list of CustomField form fields
|
||||||
|
self.custom_fields.append(field_name)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomFieldModelForm(forms.ModelForm):
|
||||||
|
"""
|
||||||
|
Extend ModelForm to include custom field support.
|
||||||
|
"""
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
self.obj_type = ContentType.objects.get_for_model(self._meta.model)
|
self.obj_type = ContentType.objects.get_for_model(self._meta.model)
|
||||||
|
Loading…
Reference in New Issue
Block a user