mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-09 21:32:17 -06:00
Compare commits
3 Commits
d571cb4867
...
14c4aeca54
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14c4aeca54 | ||
|
|
26bec1275f | ||
|
|
fa2d7f6516 |
@@ -1335,6 +1335,13 @@ class MACAddressImportForm(NetBoxModelImportForm):
|
||||
|
||||
class CableImportForm(NetBoxModelImportForm):
|
||||
# Termination A
|
||||
side_a_site = CSVModelChoiceField(
|
||||
label=_('Side A site'),
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
to_field_name='name',
|
||||
help_text=_('Site of parent device A (if any)'),
|
||||
)
|
||||
side_a_device = CSVModelChoiceField(
|
||||
label=_('Side A device'),
|
||||
queryset=Device.objects.all(),
|
||||
@@ -1353,6 +1360,13 @@ class CableImportForm(NetBoxModelImportForm):
|
||||
)
|
||||
|
||||
# Termination B
|
||||
side_b_site = CSVModelChoiceField(
|
||||
label=_('Side B site'),
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
to_field_name='name',
|
||||
help_text=_('Site of parent device B (if any)'),
|
||||
)
|
||||
side_b_device = CSVModelChoiceField(
|
||||
label=_('Side B device'),
|
||||
queryset=Device.objects.all(),
|
||||
@@ -1400,10 +1414,29 @@ class CableImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = Cable
|
||||
fields = [
|
||||
'side_a_device', 'side_a_type', 'side_a_name', 'side_b_device', 'side_b_type', 'side_b_name', 'type',
|
||||
'status', 'tenant', 'label', 'color', 'length', 'length_unit', 'description', 'comments', 'tags',
|
||||
'side_a_site', 'side_a_device', 'side_a_type', 'side_a_name', 'side_b_site', 'side_b_device', 'side_b_type',
|
||||
'side_b_name', 'type', 'status', 'tenant', 'label', 'color', 'length', 'length_unit', 'description',
|
||||
'comments', 'tags',
|
||||
]
|
||||
|
||||
def __init__(self, data=None, *args, **kwargs):
|
||||
super().__init__(data, *args, **kwargs)
|
||||
|
||||
if data:
|
||||
# Limit choices for side_a_device to the assigned side_a_site
|
||||
if side_a_site := data.get('side_a_site'):
|
||||
side_a_device_params = {f'site__{self.fields["side_a_site"].to_field_name}': side_a_site}
|
||||
self.fields['side_a_device'].queryset = self.fields['side_a_device'].queryset.filter(
|
||||
**side_a_device_params
|
||||
)
|
||||
|
||||
# Limit choices for side_b_device to the assigned side_b_site
|
||||
if side_b_site := data.get('side_b_site'):
|
||||
side_b_device_params = {f'site__{self.fields["side_b_site"].to_field_name}': side_b_site}
|
||||
self.fields['side_b_device'].queryset = self.fields['side_b_device'].queryset.filter(
|
||||
**side_b_device_params
|
||||
)
|
||||
|
||||
def _clean_side(self, side):
|
||||
"""
|
||||
Derive a Cable's A/B termination objects.
|
||||
|
||||
@@ -3266,17 +3266,27 @@ class CableTestCase(
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
|
||||
site = Site.objects.create(name='Site 1', slug='site-1')
|
||||
sites = (
|
||||
Site(name='Site 1', slug='site-1'),
|
||||
Site(name='Site 2', slug='site-2'),
|
||||
)
|
||||
Site.objects.bulk_create(sites)
|
||||
manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
|
||||
devicetype = DeviceType.objects.create(model='Device Type 1', manufacturer=manufacturer)
|
||||
role = DeviceRole.objects.create(name='Device Role 1', slug='device-role-1')
|
||||
vc = VirtualChassis.objects.create(name='Virtual Chassis')
|
||||
|
||||
# NOTE: By design, NetBox now allows for the creation of devices with the same name if they belong to
|
||||
# different sites.
|
||||
# The CSV test below demonstrates that devices with identical names on different sites can be created
|
||||
# and referenced successfully.
|
||||
devices = (
|
||||
Device(name='Device 1', site=site, device_type=devicetype, role=role),
|
||||
Device(name='Device 2', site=site, device_type=devicetype, role=role),
|
||||
Device(name='Device 3', site=site, device_type=devicetype, role=role),
|
||||
Device(name='Device 4', site=site, device_type=devicetype, role=role),
|
||||
# Create 'Device 1' assigned to 'Site 1'
|
||||
Device(name='Device 1', site=sites[0], device_type=devicetype, role=role),
|
||||
Device(name='Device 2', site=sites[0], device_type=devicetype, role=role),
|
||||
Device(name='Device 3', site=sites[0], device_type=devicetype, role=role),
|
||||
# Create 'Device 1' assigned to 'Site 2' (allowed since the site is different)
|
||||
Device(name='Device 1', site=sites[1], device_type=devicetype, role=role),
|
||||
)
|
||||
Device.objects.bulk_create(devices)
|
||||
|
||||
@@ -3327,13 +3337,15 @@ class CableTestCase(
|
||||
'tags': [t.pk for t in tags],
|
||||
}
|
||||
|
||||
# Ensure that CSV bulk import supports assigning terminations from parent devices that share
|
||||
# the same device name, provided those devices belong to different sites.
|
||||
cls.csv_data = (
|
||||
"side_a_device,side_a_type,side_a_name,side_b_device,side_b_type,side_b_name",
|
||||
"Device 3,dcim.interface,Interface 1,Device 4,dcim.interface,Interface 1",
|
||||
"Device 3,dcim.interface,Interface 2,Device 4,dcim.interface,Interface 2",
|
||||
"Device 3,dcim.interface,Interface 3,Device 4,dcim.interface,Interface 3",
|
||||
"Device 1,dcim.interface,Device 2 Interface,Device 4,dcim.interface,Interface 4",
|
||||
"Device 1,dcim.interface,Device 3 Interface,Device 4,dcim.interface,Interface 5",
|
||||
"side_a_site,side_a_device,side_a_type,side_a_name,side_b_site,side_b_device,side_b_type,side_b_name",
|
||||
"Site 1,Device 3,dcim.interface,Interface 1,Site 2,Device 1,dcim.interface,Interface 1",
|
||||
"Site 1,Device 3,dcim.interface,Interface 2,Site 2,Device 1,dcim.interface,Interface 2",
|
||||
"Site 1,Device 3,dcim.interface,Interface 3,Site 2,Device 1,dcim.interface,Interface 3",
|
||||
"Site 1,Device 1,dcim.interface,Device 2 Interface,Site 2,Device 1,dcim.interface,Interface 4",
|
||||
"Site 1,Device 1,dcim.interface,Device 3 Interface,Site 2,Device 1,dcim.interface,Interface 5",
|
||||
)
|
||||
|
||||
cls.csv_update_data = (
|
||||
|
||||
2
netbox/project-static/dist/netbox.js
vendored
2
netbox/project-static/dist/netbox.js
vendored
File diff suppressed because one or more lines are too long
6
netbox/project-static/dist/netbox.js.map
vendored
6
netbox/project-static/dist/netbox.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -35,7 +35,7 @@ function showRackElements(
|
||||
selector: string,
|
||||
elevation: HTMLObjectElement,
|
||||
): void {
|
||||
const elements = elevation.contentDocument?.querySelectorAll(selector) ?? [];
|
||||
const elements = elevation.querySelectorAll(selector) ?? [];
|
||||
for (const element of elements) {
|
||||
element.classList.remove('hidden');
|
||||
}
|
||||
@@ -45,7 +45,7 @@ function hideRackElements(
|
||||
selector: string,
|
||||
elevation: HTMLObjectElement,
|
||||
): void {
|
||||
const elements = elevation.contentDocument?.querySelectorAll(selector) ?? [];
|
||||
const elements = elevation.querySelectorAll(selector) ?? [];
|
||||
for (const element of elements) {
|
||||
element.classList.add('hidden');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% load i18n %}
|
||||
<div style="margin-left: -30px">
|
||||
<div style="margin-left: -30px" class="rack_elevation">
|
||||
<div
|
||||
hx-get="{% url 'dcim-api:rack-elevation' pk=object.pk %}?face={{ face }}&render=svg{% if extra_params %}&{{ extra_params }}{% endif %}"
|
||||
hx-trigger="intersect"
|
||||
|
||||
@@ -45,12 +45,17 @@ class TenantBulkEditForm(NetBoxModelBulkEditForm):
|
||||
queryset=TenantGroup.objects.all(),
|
||||
required=False
|
||||
)
|
||||
description = forms.CharField(
|
||||
label=_('Description'),
|
||||
max_length=200,
|
||||
required=False
|
||||
)
|
||||
|
||||
model = Tenant
|
||||
fieldsets = (
|
||||
FieldSet('group'),
|
||||
FieldSet('group', 'description'),
|
||||
)
|
||||
nullable_fields = ('group',)
|
||||
nullable_fields = ('group', 'description')
|
||||
|
||||
|
||||
#
|
||||
|
||||
@@ -98,6 +98,7 @@ class TenantTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
|
||||
cls.bulk_edit_data = {
|
||||
'group': tenant_groups[1].pk,
|
||||
'description': 'Bulk edit description',
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user