mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Move null_option to DynamicModelChoiceMixin
This commit is contained in:
@ -672,9 +672,7 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
|
||||
),
|
||||
required=False,
|
||||
label='Rack group',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=RackStatusChoices,
|
||||
@ -685,9 +683,7 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
|
||||
queryset=RackRole.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
@ -853,9 +849,7 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm):
|
||||
queryset=RackGroup.objects.prefetch_related('site'),
|
||||
required=False,
|
||||
label='Rack group',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
@ -2124,9 +2118,7 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
||||
queryset=Rack.objects.all(),
|
||||
required=False,
|
||||
label='Rack',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
role = DynamicModelMultipleChoiceField(
|
||||
queryset=DeviceRole.objects.all(),
|
||||
@ -2155,9 +2147,7 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
||||
queryset=Platform.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=DeviceStatusChoices,
|
||||
@ -3879,8 +3869,8 @@ class CableFilterForm(BootstrapMixin, forms.Form):
|
||||
queryset=Rack.objects.all(),
|
||||
required=False,
|
||||
label='Rack',
|
||||
null_option='None',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
filter_for={
|
||||
'device_id': 'rack_id',
|
||||
}
|
||||
@ -4208,8 +4198,8 @@ class VirtualChassisFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
queryset=TenantGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
null_option='None',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
filter_for={
|
||||
'tenant': 'group'
|
||||
}
|
||||
@ -4219,9 +4209,7 @@ class VirtualChassisFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
queryset=Tenant.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
@ -4336,9 +4324,7 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
queryset=RackGroup.objects.all(),
|
||||
required=False,
|
||||
label='Rack group (ID)',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
@ -4555,17 +4541,13 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
queryset=PowerPanel.objects.all(),
|
||||
required=False,
|
||||
label='Power panel',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
rack_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
required=False,
|
||||
label='Rack',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=PowerFeedStatusChoices,
|
||||
|
@ -464,9 +464,7 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
|
||||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label='VRF',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='Global'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=PrefixStatusChoices,
|
||||
@ -487,17 +485,13 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
role = DynamicModelMultipleChoiceField(
|
||||
queryset=Role.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
is_pool = forms.NullBooleanField(
|
||||
required=False,
|
||||
@ -910,9 +904,7 @@ class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterFo
|
||||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label='VRF',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='Global'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=IPAddressStatusChoices,
|
||||
@ -981,9 +973,7 @@ class VLANGroupFilterForm(BootstrapMixin, forms.Form):
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
|
||||
|
||||
@ -1147,17 +1137,13 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=VLANGroup.objects.all(),
|
||||
required=False,
|
||||
label='VLAN group',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=VLANStatusChoices,
|
||||
@ -1168,9 +1154,7 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
|
||||
queryset=Role.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
@ -247,7 +247,7 @@ $(document).ready(function() {
|
||||
if (element.getAttribute('data-null-option') && data.previous === null) {
|
||||
results.unshift({
|
||||
id: 'null',
|
||||
text: 'None'
|
||||
text: element.getAttribute('data-null-option')
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -106,9 +106,7 @@ class TenantFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
queryset=TenantGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
@ -152,8 +150,8 @@ class TenancyFilterForm(forms.Form):
|
||||
queryset=TenantGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
null_option='None',
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
filter_for={
|
||||
'tenant': 'group'
|
||||
}
|
||||
@ -163,7 +161,5 @@ class TenancyFilterForm(forms.Form):
|
||||
queryset=Tenant.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
|
@ -245,12 +245,18 @@ class TagFilterField(forms.MultipleChoiceField):
|
||||
|
||||
|
||||
class DynamicModelChoiceMixin:
|
||||
"""
|
||||
:param display_field: The name of the attribute of an API response object to display in the selection list
|
||||
:param query_params: A dictionary of additional key/value pairs to attach to the API request
|
||||
:param null_option: The string used to represent a null selection (if any)
|
||||
"""
|
||||
filter = django_filters.ModelChoiceFilter
|
||||
widget = widgets.APISelect
|
||||
|
||||
def __init__(self, *args, display_field='name', query_params=None, **kwargs):
|
||||
def __init__(self, *args, display_field='name', query_params=None, null_option=None, **kwargs):
|
||||
self.display_field = display_field
|
||||
self.query_params = query_params or {}
|
||||
self.null_option = null_option
|
||||
|
||||
# to_field_name is set by ModelChoiceField.__init__(), but we need to set it early for reference
|
||||
# by widget_attrs()
|
||||
@ -267,6 +273,10 @@ class DynamicModelChoiceMixin:
|
||||
if self.to_field_name:
|
||||
attrs['value-field'] = self.to_field_name
|
||||
|
||||
# Set the string used to represent a null option
|
||||
if self.null_option is not None:
|
||||
attrs['data-null-option'] = self.null_option
|
||||
|
||||
# Attach any static query parameters
|
||||
for key, value in self.query_params.items():
|
||||
widget.add_additional_query_param(key, value)
|
||||
|
@ -146,7 +146,6 @@ class APISelect(SelectWithDisabled):
|
||||
name of the filter-for field (child field) and the value is the name of the query param filter.
|
||||
:param additional_query_params: Optional) A dict of query params to append to the API request. The key is the
|
||||
name of the query param and the value if the query param's value.
|
||||
:param null_option: If true, include the static null option in the selection list.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
@ -155,7 +154,6 @@ class APISelect(SelectWithDisabled):
|
||||
disabled_indicator=None,
|
||||
filter_for=None,
|
||||
additional_query_params=None,
|
||||
null_option=False,
|
||||
full=False,
|
||||
*args,
|
||||
**kwargs
|
||||
@ -178,8 +176,6 @@ class APISelect(SelectWithDisabled):
|
||||
if additional_query_params:
|
||||
for key, value in additional_query_params.items():
|
||||
self.add_additional_query_param(key, value)
|
||||
if null_option:
|
||||
self.attrs['data-null-option'] = 1
|
||||
|
||||
def add_filter_for(self, name, value):
|
||||
"""
|
||||
|
@ -182,17 +182,13 @@ class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
group = DynamicModelMultipleChoiceField(
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
@ -485,17 +481,13 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFil
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
cluster_type = DynamicModelMultipleChoiceField(
|
||||
queryset=ClusterType.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
cluster_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Cluster.objects.all(),
|
||||
@ -516,18 +508,16 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFil
|
||||
queryset=Site.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
role = DynamicModelMultipleChoiceField(
|
||||
queryset=DeviceRole.objects.filter(vm_role=True),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
null_option='None',
|
||||
query_params={
|
||||
'vm_role': "True"
|
||||
},
|
||||
widget=APISelectMultiple(null_option=True)
|
||||
}
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=VirtualMachineStatusChoices,
|
||||
@ -538,9 +528,7 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFil
|
||||
queryset=Platform.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
widget=APISelectMultiple(
|
||||
null_option=True,
|
||||
)
|
||||
null_option='None'
|
||||
)
|
||||
mac_address = forms.CharField(
|
||||
required=False,
|
||||
|
Reference in New Issue
Block a user