mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-27 19:08:38 -06:00
OMS-559 Duplicate platform names allowed for different manufacturers
This commit is contained in:
parent
c324d23634
commit
b110201d29
23
netbox/dcim/migrations/0201_alter_platform_name_and_more.py
Normal file
23
netbox/dcim/migrations/0201_alter_platform_name_and_more.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-02-19 09:24
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0200_populate_mac_addresses'),
|
||||||
|
('extras', '0122_charfield_null_choices'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='platform',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=100),
|
||||||
|
),
|
||||||
|
migrations.AddConstraint(
|
||||||
|
model_name='platform',
|
||||||
|
constraint=models.UniqueConstraint(fields=('name', 'manufacturer'), name='unique_platform_per_manufacturer'),
|
||||||
|
),
|
||||||
|
]
|
@ -502,6 +502,10 @@ class Platform(OrganizationalModel):
|
|||||||
Platform refers to the software or firmware running on a Device. For example, "Cisco IOS-XR" or "Juniper Junos". A
|
Platform refers to the software or firmware running on a Device. For example, "Cisco IOS-XR" or "Juniper Junos". A
|
||||||
Platform may optionally be associated with a particular Manufacturer.
|
Platform may optionally be associated with a particular Manufacturer.
|
||||||
"""
|
"""
|
||||||
|
name = models.CharField(
|
||||||
|
verbose_name=_('name'),
|
||||||
|
max_length=100
|
||||||
|
)
|
||||||
manufacturer = models.ForeignKey(
|
manufacturer = models.ForeignKey(
|
||||||
to='dcim.Manufacturer',
|
to='dcim.Manufacturer',
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
@ -522,7 +526,12 @@ class Platform(OrganizationalModel):
|
|||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
verbose_name = _('platform')
|
verbose_name = _('platform')
|
||||||
verbose_name_plural = _('platforms')
|
verbose_name_plural = _('platforms')
|
||||||
|
constraints = [
|
||||||
|
models.UniqueConstraint(
|
||||||
|
fields=['name', 'manufacturer'],
|
||||||
|
name='unique_platform_per_manufacturer'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
def update_interface_bridges(device, interface_templates, module=None):
|
def update_interface_bridges(device, interface_templates, module=None):
|
||||||
"""
|
"""
|
||||||
|
@ -2,7 +2,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
|
|
||||||
from dcim.choices import InterfaceModeChoices
|
from dcim.choices import InterfaceModeChoices
|
||||||
from dcim.forms.mixins import ScopedImportForm
|
from dcim.forms.mixins import ScopedImportForm
|
||||||
from dcim.models import Device, DeviceRole, Platform, Site
|
from dcim.models import Device, DeviceRole, Platform, Site, Manufacturer
|
||||||
from extras.models import ConfigTemplate
|
from extras.models import ConfigTemplate
|
||||||
from ipam.models import VRF
|
from ipam.models import VRF
|
||||||
from netbox.forms import NetBoxModelImportForm
|
from netbox.forms import NetBoxModelImportForm
|
||||||
@ -124,6 +124,13 @@ class VirtualMachineImportForm(NetBoxModelImportForm):
|
|||||||
to_field_name='name',
|
to_field_name='name',
|
||||||
help_text=_('Assigned tenant')
|
help_text=_('Assigned tenant')
|
||||||
)
|
)
|
||||||
|
manufacturer = CSVModelChoiceField(
|
||||||
|
label=_('Manufacturer'),
|
||||||
|
queryset=Manufacturer.objects.all(),
|
||||||
|
required=False,
|
||||||
|
to_field_name='name',
|
||||||
|
help_text=_('Device type manufacturer'),
|
||||||
|
)
|
||||||
platform = CSVModelChoiceField(
|
platform = CSVModelChoiceField(
|
||||||
label=_('Platform'),
|
label=_('Platform'),
|
||||||
queryset=Platform.objects.all(),
|
queryset=Platform.objects.all(),
|
||||||
@ -138,12 +145,25 @@ class VirtualMachineImportForm(NetBoxModelImportForm):
|
|||||||
label=_('Config template'),
|
label=_('Config template'),
|
||||||
help_text=_('Config template')
|
help_text=_('Config template')
|
||||||
)
|
)
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
manufacturer_name = self.data.get('manufacturer') or self.initial.get('manufacturer')
|
||||||
|
platform_name = self.data.get('platform') or self.initial.get('platform')
|
||||||
|
|
||||||
|
if manufacturer_name:
|
||||||
|
try:
|
||||||
|
manufacturer = Manufacturer.objects.get(name=manufacturer_name)
|
||||||
|
self.fields['platform'].queryset = Platform.objects.filter(manufacturer=manufacturer)
|
||||||
|
except Manufacturer.DoesNotExist:
|
||||||
|
self.fields['platform'].queryset = Platform.objects.none()
|
||||||
|
elif platform_name:
|
||||||
|
self.add_error('manufacturer', _("Manufacturer is required if Platform is provided"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = VirtualMachine
|
model = VirtualMachine
|
||||||
fields = (
|
fields = (
|
||||||
'name', 'status', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk',
|
'name', 'status', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk',
|
||||||
'description', 'serial', 'config_template', 'comments', 'tags',
|
'description', 'serial', 'config_template', 'comments', 'tags','manufacturer'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user