mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Fixes #1229: Fix validation error on forms where API search is used
This commit is contained in:
@ -167,7 +167,9 @@ class CircuitTerminationForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm
|
||||
)
|
||||
rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
required=False,
|
||||
label='Rack',
|
||||
widget=APISelect(
|
||||
@ -177,7 +179,10 @@ class CircuitTerminationForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm
|
||||
)
|
||||
device = ChainedModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
chains={'site': 'site', 'rack': 'rack'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
('rack', 'rack'),
|
||||
),
|
||||
required=False,
|
||||
label='Device',
|
||||
widget=APISelect(
|
||||
@ -186,20 +191,13 @@ class CircuitTerminationForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm
|
||||
attrs={'filter-for': 'interface'}
|
||||
)
|
||||
)
|
||||
livesearch = forms.CharField(
|
||||
required=False,
|
||||
label='Device',
|
||||
widget=Livesearch(
|
||||
query_key='q',
|
||||
query_url='dcim-api:device-list',
|
||||
field_to_update='device'
|
||||
)
|
||||
)
|
||||
interface = ChainedModelChoiceField(
|
||||
queryset=Interface.objects.exclude(form_factor__in=VIRTUAL_IFACE_TYPES).select_related(
|
||||
'circuit_termination', 'connected_as_a', 'connected_as_b'
|
||||
),
|
||||
chains={'device': 'device'},
|
||||
chains=(
|
||||
('device', 'device'),
|
||||
),
|
||||
required=False,
|
||||
label='Interface',
|
||||
widget=APISelect(
|
||||
@ -210,8 +208,10 @@ class CircuitTerminationForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm
|
||||
|
||||
class Meta:
|
||||
model = CircuitTermination
|
||||
fields = ['term_side', 'site', 'rack', 'device', 'livesearch', 'interface', 'port_speed', 'upstream_speed',
|
||||
'xconnect_id', 'pp_info']
|
||||
fields = [
|
||||
'term_side', 'site', 'rack', 'device', 'interface', 'port_speed', 'upstream_speed', 'xconnect_id',
|
||||
'pp_info',
|
||||
]
|
||||
help_texts = {
|
||||
'port_speed': "Physical circuit speed",
|
||||
'xconnect_id': "ID of the local cross-connect",
|
||||
|
@ -190,7 +190,9 @@ class RackRoleForm(BootstrapMixin, forms.ModelForm):
|
||||
class RackForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
group = ChainedModelChoiceField(
|
||||
queryset=RackGroup.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/rack-groups/?site_id={{site}}',
|
||||
@ -545,7 +547,9 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
)
|
||||
rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/racks/?site_id={{site}}',
|
||||
@ -570,7 +574,9 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
)
|
||||
device_type = ChainedModelChoiceField(
|
||||
queryset=DeviceType.objects.all(),
|
||||
chains={'manufacturer': 'manufacturer'},
|
||||
chains=(
|
||||
('manufacturer', 'manufacturer'),
|
||||
),
|
||||
label='Device type',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/device-types/?manufacturer_id={{manufacturer}}',
|
||||
@ -957,20 +963,29 @@ class ConsoleConnectionImportForm(BootstrapMixin, BulkImportForm):
|
||||
class ConsolePortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm):
|
||||
site = forms.ModelChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
widget=forms.HiddenInput(),
|
||||
required=False,
|
||||
widget=forms.Select(
|
||||
attrs={'filter-for': 'rack'}
|
||||
)
|
||||
)
|
||||
rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
label='Rack',
|
||||
required=False,
|
||||
widget=forms.Select(
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/racks/?site_id={{site}}',
|
||||
attrs={'filter-for': 'console_server', 'nullable': 'true'}
|
||||
)
|
||||
)
|
||||
console_server = ChainedModelChoiceField(
|
||||
queryset=Device.objects.filter(device_type__is_console_server=True),
|
||||
chains={'site': 'site', 'rack': 'rack'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
('rack', 'rack'),
|
||||
),
|
||||
label='Console Server',
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
@ -990,7 +1005,9 @@ class ConsolePortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelF
|
||||
)
|
||||
cs_port = ChainedModelChoiceField(
|
||||
queryset=ConsoleServerPort.objects.all(),
|
||||
chains={'device': 'console_server'},
|
||||
chains=(
|
||||
('device', 'console_server'),
|
||||
),
|
||||
label='Port',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/console-server-ports/?device_id={{console_server}}',
|
||||
@ -1035,20 +1052,29 @@ class ConsoleServerPortCreateForm(DeviceComponentForm):
|
||||
class ConsoleServerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.Form):
|
||||
site = forms.ModelChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
widget=forms.HiddenInput(),
|
||||
required=False,
|
||||
widget=forms.Select(
|
||||
attrs={'filter-for': 'rack'}
|
||||
)
|
||||
)
|
||||
rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
label='Rack',
|
||||
required=False,
|
||||
widget=forms.Select(
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/racks/?site_id={{site}}',
|
||||
attrs={'filter-for': 'device', 'nullable': 'true'}
|
||||
)
|
||||
)
|
||||
device = ChainedModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
chains={'site': 'site', 'rack': 'rack'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
('rack', 'rack'),
|
||||
),
|
||||
label='Device',
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
@ -1068,7 +1094,9 @@ class ConsoleServerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.
|
||||
)
|
||||
port = ChainedModelChoiceField(
|
||||
queryset=ConsolePort.objects.all(),
|
||||
chains={'device': 'device'},
|
||||
chains=(
|
||||
('device', 'device'),
|
||||
),
|
||||
label='Port',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/console-ports/?device_id={{device}}',
|
||||
@ -1182,19 +1210,31 @@ class PowerConnectionImportForm(BootstrapMixin, BulkImportForm):
|
||||
|
||||
|
||||
class PowerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm):
|
||||
site = forms.ModelChoiceField(queryset=Site.objects.all(), widget=forms.HiddenInput())
|
||||
rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
label='Rack',
|
||||
site = forms.ModelChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
widget=forms.Select(
|
||||
attrs={'filter-for': 'rack'}
|
||||
)
|
||||
)
|
||||
rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
label='Rack',
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/racks/?site_id={{site}}',
|
||||
attrs={'filter-for': 'pdu', 'nullable': 'true'}
|
||||
)
|
||||
)
|
||||
pdu = ChainedModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
chains={'site': 'site', 'rack': 'rack'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
('rack', 'rack'),
|
||||
),
|
||||
label='PDU',
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
@ -1214,7 +1254,9 @@ class PowerPortConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelFor
|
||||
)
|
||||
power_outlet = ChainedModelChoiceField(
|
||||
queryset=PowerOutlet.objects.all(),
|
||||
chains={'device': 'pdu'},
|
||||
chains=(
|
||||
('device', 'pdu'),
|
||||
),
|
||||
label='Outlet',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/power-outlets/?device_id={{pdu}}',
|
||||
@ -1259,20 +1301,29 @@ class PowerOutletCreateForm(DeviceComponentForm):
|
||||
class PowerOutletConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.Form):
|
||||
site = forms.ModelChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
required=False,
|
||||
widget=forms.Select(
|
||||
attrs={'filter-for': 'rack'}
|
||||
)
|
||||
)
|
||||
rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
label='Rack',
|
||||
required=False,
|
||||
widget=forms.Select(
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/racks/?site_id={{site}}',
|
||||
attrs={'filter-for': 'device', 'nullable': 'true'}
|
||||
)
|
||||
)
|
||||
device = ChainedModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
chains={'site': 'site', 'rack': 'rack'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
('rack', 'rack'),
|
||||
),
|
||||
label='Device',
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
@ -1292,7 +1343,9 @@ class PowerOutletConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.Form):
|
||||
)
|
||||
port = ChainedModelChoiceField(
|
||||
queryset=PowerPort.objects.all(),
|
||||
chains={'device': 'device'},
|
||||
chains=(
|
||||
('device', 'device'),
|
||||
),
|
||||
label='Port',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/power-ports/?device_id={{device}}',
|
||||
@ -1412,7 +1465,9 @@ class InterfaceConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelFor
|
||||
)
|
||||
rack_b = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'site_b'},
|
||||
chains=(
|
||||
('site', 'site_b'),
|
||||
),
|
||||
label='Rack',
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
@ -1422,7 +1477,10 @@ class InterfaceConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelFor
|
||||
)
|
||||
device_b = ChainedModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
chains={'site': 'site_b', 'rack': 'rack_b'},
|
||||
chains=(
|
||||
('site', 'site_b'),
|
||||
('rack', 'rack_b'),
|
||||
),
|
||||
label='Device',
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
@ -1444,7 +1502,9 @@ class InterfaceConnectionForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelFor
|
||||
queryset=Interface.objects.exclude(form_factor__in=VIRTUAL_IFACE_TYPES).select_related(
|
||||
'circuit_termination', 'connected_as_a', 'connected_as_b'
|
||||
),
|
||||
chains={'device': 'device_b'},
|
||||
chains=(
|
||||
('device', 'device_b'),
|
||||
),
|
||||
label='Interface',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/interfaces/?device_id={{device_b}}&type=physical',
|
||||
|
@ -944,9 +944,9 @@ def consoleport_connect(request, pk):
|
||||
|
||||
else:
|
||||
form = forms.ConsolePortConnectionForm(instance=consoleport, initial={
|
||||
'site': request.GET.get('site', consoleport.device.site),
|
||||
'rack': request.GET.get('rack', None),
|
||||
'console_server': request.GET.get('console_server', None),
|
||||
'site': request.GET.get('site'),
|
||||
'rack': request.GET.get('rack'),
|
||||
'console_server': request.GET.get('console_server'),
|
||||
'connection_status': CONNECTION_STATUS_CONNECTED,
|
||||
})
|
||||
|
||||
@ -1061,9 +1061,9 @@ def consoleserverport_connect(request, pk):
|
||||
|
||||
else:
|
||||
form = forms.ConsoleServerPortConnectionForm(initial={
|
||||
'site': request.GET.get('site', consoleserverport.device.site),
|
||||
'rack': request.GET.get('rack', None),
|
||||
'device': request.GET.get('device', None),
|
||||
'site': request.GET.get('site'),
|
||||
'rack': request.GET.get('rack'),
|
||||
'device': request.GET.get('device'),
|
||||
'connection_status': CONNECTION_STATUS_CONNECTED,
|
||||
})
|
||||
|
||||
@ -1167,9 +1167,9 @@ def powerport_connect(request, pk):
|
||||
|
||||
else:
|
||||
form = forms.PowerPortConnectionForm(instance=powerport, initial={
|
||||
'site': request.GET.get('site', powerport.device.site),
|
||||
'rack': request.GET.get('rack', None),
|
||||
'pdu': request.GET.get('pdu', None),
|
||||
'site': request.GET.get('site'),
|
||||
'rack': request.GET.get('rack'),
|
||||
'pdu': request.GET.get('pdu'),
|
||||
'connection_status': CONNECTION_STATUS_CONNECTED,
|
||||
})
|
||||
|
||||
@ -1284,9 +1284,9 @@ def poweroutlet_connect(request, pk):
|
||||
|
||||
else:
|
||||
form = forms.PowerOutletConnectionForm(initial={
|
||||
'site': request.GET.get('site', poweroutlet.device.site),
|
||||
'rack': request.GET.get('rack', None),
|
||||
'device': request.GET.get('device', None),
|
||||
'site': request.GET.get('site'),
|
||||
'rack': request.GET.get('rack'),
|
||||
'device': request.GET.get('device'),
|
||||
'connection_status': CONNECTION_STATUS_CONNECTED,
|
||||
})
|
||||
|
||||
@ -1616,11 +1616,11 @@ def interfaceconnection_add(request, pk):
|
||||
|
||||
else:
|
||||
form = forms.InterfaceConnectionForm(device, initial={
|
||||
'interface_a': request.GET.get('interface_a', None),
|
||||
'site_b': request.GET.get('site_b', device.site),
|
||||
'rack_b': request.GET.get('rack_b', None),
|
||||
'device_b': request.GET.get('device_b', None),
|
||||
'interface_b': request.GET.get('interface_b', None),
|
||||
'interface_a': request.GET.get('interface_a'),
|
||||
'site_b': request.GET.get('site_b'),
|
||||
'rack_b': request.GET.get('rack_b'),
|
||||
'device_b': request.GET.get('device_b'),
|
||||
'interface_b': request.GET.get('interface_b'),
|
||||
})
|
||||
|
||||
return render(request, 'dcim/interfaceconnection_edit.html', {
|
||||
|
@ -168,12 +168,21 @@ class RoleForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
site = forms.ModelChoiceField(
|
||||
queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select(
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
label='Site',
|
||||
widget=forms.Select(
|
||||
attrs={'filter-for': 'vlan', 'nullable': 'true'}
|
||||
)
|
||||
)
|
||||
vlan = ChainedModelChoiceField(
|
||||
queryset=VLAN.objects.all(), chains={'site': 'site'}, required=False, label='VLAN', widget=APISelect(
|
||||
queryset=VLAN.objects.all(),
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
required=False,
|
||||
label='VLAN',
|
||||
widget=APISelect(
|
||||
api_url='/api/ipam/vlans/?site_id={{site}}', display_field='display_name'
|
||||
)
|
||||
)
|
||||
@ -322,7 +331,9 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm)
|
||||
)
|
||||
interface_rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'interface_site'},
|
||||
chains=(
|
||||
('site', 'interface_site'),
|
||||
),
|
||||
required=False,
|
||||
label='Rack',
|
||||
widget=APISelect(
|
||||
@ -333,7 +344,10 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm)
|
||||
)
|
||||
interface_device = ChainedModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
chains={'site': 'interface_site', 'rack': 'interface_rack'},
|
||||
chains=(
|
||||
('site', 'interface_site'),
|
||||
('rack', 'interface_rack'),
|
||||
),
|
||||
required=False,
|
||||
label='Device',
|
||||
widget=APISelect(
|
||||
@ -344,7 +358,9 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm)
|
||||
)
|
||||
interface = ChainedModelChoiceField(
|
||||
queryset=Interface.objects.all(),
|
||||
chains={'device': 'interface_device'},
|
||||
chains=(
|
||||
('device', 'interface_device'),
|
||||
),
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/interfaces/?device_id={{interface_device}}'
|
||||
@ -355,34 +371,41 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm)
|
||||
required=False,
|
||||
label='Site',
|
||||
widget=forms.Select(
|
||||
attrs={'filter-for': 'nat_device'}
|
||||
attrs={'filter-for': 'nat_rack'}
|
||||
)
|
||||
)
|
||||
nat_rack = ChainedModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
chains={'site': 'nat_site'},
|
||||
chains=(
|
||||
('site', 'nat_site'),
|
||||
),
|
||||
required=False,
|
||||
label='Rack',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/racks/?site_id={{interface_site}}',
|
||||
api_url='/api/dcim/racks/?site_id={{nat_site}}',
|
||||
display_field='display_name',
|
||||
attrs={'filter-for': 'nat_device', 'nullable': 'true'}
|
||||
)
|
||||
)
|
||||
nat_device = ChainedModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
chains={'site': 'nat_site'},
|
||||
chains=(
|
||||
('site', 'nat_site'),
|
||||
('rack', 'nat_rack'),
|
||||
),
|
||||
required=False,
|
||||
label='Device',
|
||||
widget=APISelect(
|
||||
api_url='/api/dcim/devices/?site_id={{nat_site}}',
|
||||
api_url='/api/dcim/devices/?site_id={{nat_site}}&rack_id={{nat_rack}}',
|
||||
display_field='display_name',
|
||||
attrs={'filter-for': 'nat_inside'}
|
||||
)
|
||||
)
|
||||
nat_inside = ChainedModelChoiceField(
|
||||
queryset=IPAddress.objects.all(),
|
||||
chains={'interface__device': 'nat_device'},
|
||||
chains=(
|
||||
('interface__device', 'nat_device'),
|
||||
),
|
||||
required=False,
|
||||
label='IP Address',
|
||||
widget=APISelect(
|
||||
@ -392,7 +415,7 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm)
|
||||
)
|
||||
livesearch = forms.CharField(
|
||||
required=False,
|
||||
label='IP Address',
|
||||
label='Search',
|
||||
widget=Livesearch(
|
||||
query_key='q',
|
||||
query_url='ipam-api:ipaddress-list',
|
||||
@ -405,8 +428,8 @@ class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm)
|
||||
class Meta:
|
||||
model = IPAddress
|
||||
fields = [
|
||||
'address', 'vrf', 'status', 'description', 'interface', 'primary_for_device', 'nat_inside', 'tenant_group',
|
||||
'tenant',
|
||||
'address', 'vrf', 'status', 'description', 'interface', 'primary_for_device', 'nat_site', 'nat_rack',
|
||||
'nat_inside', 'tenant_group', 'tenant',
|
||||
]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@ -627,7 +650,9 @@ class VLANForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
)
|
||||
group = ChainedModelChoiceField(
|
||||
queryset=VLANGroup.objects.all(),
|
||||
chains={'site': 'site'},
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
required=False,
|
||||
label='Group',
|
||||
widget=APISelect(
|
||||
|
@ -45,23 +45,8 @@
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.site %}
|
||||
<div class="row">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active"><a href="#select" aria-controls="home" role="tab" data-toggle="tab">Select</a></li>
|
||||
<li role="presentation"><a href="#search" aria-controls="search" role="tab" data-toggle="tab">Search</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="select">
|
||||
{% render_field form.rack %}
|
||||
{% render_field form.device %}
|
||||
</div>
|
||||
<div class="tab-pane" id="search">
|
||||
{% render_field form.livesearch %}
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.interface %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -32,12 +32,7 @@
|
||||
{% render_field form.livesearch %}
|
||||
</div>
|
||||
<div class="tab-pane" id="select">
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Site</label>
|
||||
<div class="col-md-9">
|
||||
<p class="form-control-static">{{ consoleport.device.site }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.site %}
|
||||
{% render_field form.rack %}
|
||||
{% render_field form.console_server %}
|
||||
</div>
|
||||
|
@ -32,12 +32,7 @@
|
||||
{% render_field form.livesearch %}
|
||||
</div>
|
||||
<div class="tab-pane" id="select">
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Site</label>
|
||||
<div class="col-md-9">
|
||||
<p class="form-control-static">{{ consoleserverport.device.site }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.site %}
|
||||
{% render_field form.rack %}
|
||||
{% render_field form.device %}
|
||||
</div>
|
||||
|
@ -32,12 +32,7 @@
|
||||
{% render_field form.livesearch %}
|
||||
</div>
|
||||
<div class="tab-pane" id="select">
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Site</label>
|
||||
<div class="col-md-9">
|
||||
<p class="form-control-static">{{ poweroutlet.device.site }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.site %}
|
||||
{% render_field form.rack %}
|
||||
{% render_field form.device %}
|
||||
</div>
|
||||
|
@ -32,12 +32,7 @@
|
||||
{% render_field form.livesearch %}
|
||||
</div>
|
||||
<div class="tab-pane" id="select">
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Site</label>
|
||||
<div class="col-md-9">
|
||||
<p class="form-control-static">{{ powerport.device.site }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.site %}
|
||||
{% render_field form.rack %}
|
||||
{% render_field form.pdu %}
|
||||
</div>
|
||||
|
@ -47,6 +47,7 @@
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="select">
|
||||
{% render_field form.nat_site %}
|
||||
{% render_field form.nat_rack %}
|
||||
{% render_field form.nat_device %}
|
||||
</div>
|
||||
<div class="tab-pane" id="search">
|
||||
|
@ -81,7 +81,9 @@ class TenancyForm(ChainedFieldsMixin, forms.Form):
|
||||
)
|
||||
tenant = ChainedModelChoiceField(
|
||||
queryset=Tenant.objects.all(),
|
||||
chains={'group': 'tenant_group'},
|
||||
chains=(
|
||||
('group', 'tenant_group'),
|
||||
),
|
||||
required=False,
|
||||
widget=APISelect(
|
||||
api_url='/api/tenancy/tenants/?group_id={{tenant_group}}'
|
||||
|
@ -443,17 +443,19 @@ class ChainedFieldsMixin(forms.BaseForm):
|
||||
if isinstance(field, ChainedModelChoiceField):
|
||||
|
||||
filters_dict = {}
|
||||
for db_field, parent_field in field.chains.items():
|
||||
for (db_field, parent_field) in field.chains:
|
||||
if self.is_bound and self.data.get(parent_field):
|
||||
filters_dict[db_field] = self.data[parent_field]
|
||||
elif self.initial.get(parent_field):
|
||||
filters_dict[db_field] = self.initial[parent_field]
|
||||
elif self.fields[parent_field].widget.attrs.get('nullable'):
|
||||
filters_dict[db_field] = None
|
||||
else:
|
||||
break
|
||||
|
||||
if filters_dict:
|
||||
field.queryset = field.queryset.filter(**filters_dict)
|
||||
else:
|
||||
elif not self.is_bound:
|
||||
field.queryset = field.queryset.none()
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user