Skip to content

Commit

Permalink
Leverage HTMX to simplify rendering of VLAN Form
Browse files Browse the repository at this point in the history
Associated with issue netbox-community#11891
  • Loading branch information
dhenschen committed Jun 2, 2023
1 parent dee4aec commit 5c4e2fe
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 74 deletions.
10 changes: 10 additions & 0 deletions netbox/ipam/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ class VLANStatusChoices(ChoiceSet):
]


class VLANAssignmentTypeChoices(ChoiceSet):
VLAN_GROUP = 'vlan_group'
SITE = 'site'

CHOICES = [
(VLAN_GROUP, 'VLAN Group'),
(SITE, 'Site'),
]


#
# Services
#
Expand Down
37 changes: 34 additions & 3 deletions netbox/ipam/forms/model_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, NumericArrayField,
SlugField,
)
from utilities.forms.widgets import DatePicker
from utilities.forms.utils import get_field_value
from utilities.forms.widgets import DatePicker, HTMXSelect
from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface

__all__ = (
Expand Down Expand Up @@ -633,12 +634,42 @@ class VLANForm(TenancyForm, NetBoxModelForm):
)
comments = CommentField()

fieldsets = (
('VLAN', ('vid', 'name', 'status', 'role', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')),
('Assignment', ('assignment_type', 'site', 'group')),
)

class Meta:
model = VLAN
fields = [
'site', 'group', 'vid', 'name', 'status', 'role', 'tenant_group', 'tenant', 'description', 'comments',
'tags',
'assignment_type', 'site', 'group', 'vid', 'name', 'status', 'role', 'tenant_group', 'tenant',
'description', 'comments', 'tags',
]
widgets = {
'assignment_type': HTMXSelect(),
}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

assignment_type = get_field_value(self, 'assignment_type')

if assignment_type != VLANAssignmentTypeChoices.VLAN_GROUP:
del self.fields['group']
if assignment_type != VLANAssignmentTypeChoices.SITE:
del self.fields['site']

def clean(self):
super().clean()

assignment_type = self.cleaned_data.get('assignment_type')

if assignment_type != VLANAssignmentTypeChoices.VLAN_GROUP:
self.cleaned_data['group'] = None

if assignment_type != VLANAssignmentTypeChoices.SITE:
self.cleaned_data['site'] = None


class ServiceTemplateForm(NetBoxModelForm):
Expand Down
37 changes: 37 additions & 0 deletions netbox/ipam/migrations/0067_vlan_assignment_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import sys
from django.db import migrations, models
from ipam.choices import VLANAssignmentTypeChoices


def populate_assignment_type_field(apps, schema_editor):
VLAN = apps.get_model('ipam', 'VLAN')

total_count = VLAN.objects.count()
if 'test' not in sys.argv:
print(f'\nUpdating {total_count} VLANs...')

for row in VLAN.objects.all():
if row.group:
row.assignment_type = VLANAssignmentTypeChoices.VLAN_GROUP
elif row.site:
row.assignment_type = VLANAssignmentTypeChoices.SITE
else:
# Assign the default value if nothing else matches
row.assignment_type = VLANAssignmentTypeChoices.VLAN_GROUP
row.save()


class Migration(migrations.Migration):

dependencies = [
('ipam', '0066_iprange_mark_utilized'),
]

operations = [
migrations.AddField(
model_name='vlan',
name='assignment_type',
field=models.CharField(default='vlan_group', max_length=50),
),
migrations.RunPython(populate_assignment_type_field),
]
8 changes: 7 additions & 1 deletion netbox/ipam/models/vlans.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ class VLAN(PrimaryModel):
Like Prefixes, each VLAN is assigned an operational status and optionally a user-defined Role. A VLAN can have zero
or more Prefixes assigned to it.
"""
assignment_type = models.CharField(
verbose_name='Assignment Type',
max_length=50,
choices=VLANAssignmentTypeChoices,
default=VLANAssignmentTypeChoices.VLAN_GROUP
)
site = models.ForeignKey(
to='dcim.Site',
on_delete=models.PROTECT,
Expand Down Expand Up @@ -183,7 +189,7 @@ class VLAN(PrimaryModel):
objects = VLANQuerySet.as_manager()

clone_fields = [
'site', 'group', 'tenant', 'status', 'role', 'description',
'assignment_type', 'site', 'group', 'tenant', 'status', 'role', 'description',
]

class Meta:
Expand Down
4 changes: 2 additions & 2 deletions netbox/ipam/tables/vlans.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ class VLANTable(TenancyColumnsMixin, NetBoxTable):
class Meta(NetBoxTable.Meta):
model = VLAN
fields = (
'pk', 'id', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'tenant_group', 'status', 'role',
'description', 'comments', 'tags', 'l2vpn', 'created', 'last_updated',
'pk', 'id', 'vid', 'name', 'assignment_type', 'site', 'group', 'prefixes', 'tenant', 'tenant_group',
'status', 'role', 'description', 'comments', 'tags', 'l2vpn', 'created', 'last_updated',
)
default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description')
row_attrs = {
Expand Down
1 change: 1 addition & 0 deletions netbox/ipam/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,7 @@ def setUpTestData(cls):
tags = create_tags('Alpha', 'Bravo', 'Charlie')

cls.form_data = {
'assignment_type': VLANAssignmentTypeChoices.VLAN_GROUP,
'site': sites[1].pk,
'group': vlangroups[1].pk,
'vid': 999,
Expand Down
1 change: 0 additions & 1 deletion netbox/ipam/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,6 @@ def get_children(self, request, parent):
class VLANEditView(generic.ObjectEditView):
queryset = VLAN.objects.all()
form = forms.VLANForm
template_name = 'ipam/vlan_edit.html'


@register_model_view(VLAN, 'delete')
Expand Down
67 changes: 0 additions & 67 deletions netbox/templates/ipam/vlan_edit.html

This file was deleted.

0 comments on commit 5c4e2fe

Please sign in to comment.