From faa12abc70efa8a05c6166fd3066dd91f6644351 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 26 Jul 2016 17:28:46 -0400 Subject: [PATCH] Enabled filtering of sites, racks, and devices by tenant --- netbox/dcim/filters.py | 34 ++++++++++++++++++++++++++++ netbox/dcim/forms.py | 24 ++++++++++++++++++++ netbox/dcim/views.py | 1 + netbox/templates/dcim/site_list.html | 1 + 4 files changed, 60 insertions(+) diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 0a4b14150..08f0d671e 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -6,6 +6,7 @@ from .models import ( ConsolePort, ConsoleServerPort, Device, DeviceRole, DeviceType, Interface, InterfaceConnection, Manufacturer, Platform, PowerOutlet, PowerPort, Rack, RackGroup, Site, ) +from tenancy.models import Tenant class SiteFilter(django_filters.FilterSet): @@ -13,6 +14,17 @@ class SiteFilter(django_filters.FilterSet): action='search', label='Search', ) + tenant_id = django_filters.ModelMultipleChoiceFilter( + name='tenant', + queryset=Tenant.objects.all(), + label='Tenant (ID)', + ) + tenant = django_filters.ModelMultipleChoiceFilter( + name='tenant', + queryset=Tenant.objects.all(), + to_field_name='slug', + label='Tenant (slug)', + ) class Meta: model = Site @@ -74,6 +86,17 @@ class RackFilter(django_filters.FilterSet): to_field_name='slug', label='Group', ) + tenant_id = django_filters.ModelMultipleChoiceFilter( + name='tenant', + queryset=Tenant.objects.all(), + label='Tenant (ID)', + ) + tenant = django_filters.ModelMultipleChoiceFilter( + name='tenant', + queryset=Tenant.objects.all(), + to_field_name='slug', + label='Tenant (slug)', + ) class Meta: model = Rack @@ -143,6 +166,17 @@ class DeviceFilter(django_filters.FilterSet): to_field_name='slug', label='Role (slug)', ) + tenant_id = django_filters.ModelMultipleChoiceFilter( + name='tenant', + queryset=Tenant.objects.all(), + label='Tenant (ID)', + ) + tenant = django_filters.ModelMultipleChoiceFilter( + name='tenant', + queryset=Tenant.objects.all(), + to_field_name='slug', + label='Tenant (slug)', + ) device_type_id = django_filters.ModelMultipleChoiceFilter( name='device_type', queryset=DeviceType.objects.all(), diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index c755a55a0..9658de907 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -76,6 +76,16 @@ class SiteImportForm(BulkImportForm, BootstrapMixin): csv = CSVDataField(csv_form=SiteFromCSVForm) +def site_tenant_choices(): + tenant_choices = Tenant.objects.annotate(site_count=Count('sites')) + return [(t.slug, u'{} ({})'.format(t.name, t.site_count)) for t in tenant_choices] + + +class SiteFilterForm(forms.Form, BootstrapMixin): + tenant = forms.MultipleChoiceField(required=False, choices=site_tenant_choices, + widget=forms.SelectMultiple(attrs={'size': 8})) + + # # Rack groups # @@ -181,11 +191,18 @@ def rack_group_choices(): return [(g.pk, u'{} ({})'.format(g, g.rack_count)) for g in group_choices] +def rack_tenant_choices(): + tenant_choices = Tenant.objects.annotate(rack_count=Count('racks')) + return [(t.slug, u'{} ({})'.format(t.name, t.rack_count)) for t in tenant_choices] + + class RackFilterForm(forms.Form, BootstrapMixin): site = forms.MultipleChoiceField(required=False, choices=rack_site_choices, widget=forms.SelectMultiple(attrs={'size': 8})) group_id = forms.MultipleChoiceField(required=False, choices=rack_group_choices, label='Rack Group', widget=forms.SelectMultiple(attrs={'size': 8})) + tenant = forms.MultipleChoiceField(required=False, choices=rack_tenant_choices, + widget=forms.SelectMultiple(attrs={'size': 8})) # @@ -542,6 +559,11 @@ def device_role_choices(): return [(r.slug, u'{} ({})'.format(r.name, r.device_count)) for r in role_choices] +def device_tenant_choices(): + tenant_choices = Tenant.objects.annotate(device_count=Count('devices')) + return [(t.slug, u'{} ({})'.format(t.name, t.device_count)) for t in tenant_choices] + + def device_type_choices(): type_choices = DeviceType.objects.select_related('manufacturer').annotate(device_count=Count('instances')) return [(t.pk, u'{} ({})'.format(t, t.device_count)) for t in type_choices] @@ -559,6 +581,8 @@ class DeviceFilterForm(forms.Form, BootstrapMixin): widget=forms.SelectMultiple(attrs={'size': 8})) role = forms.MultipleChoiceField(required=False, choices=device_role_choices, widget=forms.SelectMultiple(attrs={'size': 8})) + tenant = forms.MultipleChoiceField(required=False, choices=device_tenant_choices, + widget=forms.SelectMultiple(attrs={'size': 8})) device_type_id = forms.MultipleChoiceField(required=False, choices=device_type_choices, label='Type', widget=forms.SelectMultiple(attrs={'size': 8})) platform = forms.MultipleChoiceField(required=False, choices=device_platform_choices) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 0d1034974..dc09403b3 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -63,6 +63,7 @@ def expand_pattern(string): class SiteListView(ObjectListView): queryset = Site.objects.select_related('tenant') filter = filters.SiteFilter + filter_form = forms.SiteFilterForm table = tables.SiteTable template_name = 'dcim/site_list.html' diff --git a/netbox/templates/dcim/site_list.html b/netbox/templates/dcim/site_list.html index d35410443..0c04faa27 100644 --- a/netbox/templates/dcim/site_list.html +++ b/netbox/templates/dcim/site_list.html @@ -37,6 +37,7 @@ + {% include 'inc/filter_panel.html' %} {% endblock %}