Просмотр исходного кода

Added filters for power panels & feeds

Jeremy Stretch 7 лет назад
Родитель
Сommit
705f82e416
5 измененных файлов с 172 добавлено и 11 удалено
  1. 2 2
      netbox/dcim/api/views.py
  2. 83 4
      netbox/dcim/filters.py
  3. 76 0
      netbox/dcim/forms.py
  4. 7 4
      netbox/dcim/views.py
  5. 4 1
      netbox/templates/dcim/powerpanel_list.html

+ 2 - 2
netbox/dcim/api/views.py

@@ -542,7 +542,7 @@ class VirtualChassisViewSet(ModelViewSet):
 class PowerPanelViewSet(ModelViewSet):
 class PowerPanelViewSet(ModelViewSet):
     queryset = PowerPanel.objects.all()
     queryset = PowerPanel.objects.all()
     serializer_class = serializers.PowerPanelSerializer
     serializer_class = serializers.PowerPanelSerializer
-    # filterset_class = filters.PowerPanelFilter
+    filterset_class = filters.PowerPanelFilter
 
 
 
 
 #
 #
@@ -552,7 +552,7 @@ class PowerPanelViewSet(ModelViewSet):
 class PowerFeedViewSet(ModelViewSet):
 class PowerFeedViewSet(ModelViewSet):
     queryset = PowerFeed.objects.all()
     queryset = PowerFeed.objects.all()
     serializer_class = serializers.PowerFeedSerializer
     serializer_class = serializers.PowerFeedSerializer
-    # filterset_class = filters.PowerFeedFilter
+    filterset_class = filters.PowerFeedFilter
 
 
 
 
 #
 #

+ 83 - 4
netbox/dcim/filters.py

@@ -15,8 +15,9 @@ from .constants import *
 from .models import (
 from .models import (
     Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
     Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
     DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
     DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
-    InventoryItem, Manufacturer, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack,
-    RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis,
+    InventoryItem, Manufacturer, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort,
+    PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
+    VirtualChassis,
 )
 )
 
 
 
 
@@ -37,7 +38,7 @@ class RegionFilter(NameSlugSearchFilterSet):
         fields = ['name', 'slug']
         fields = ['name', 'slug']
 
 
 
 
-class SiteFilter(CustomFieldFilterSet, django_filters.FilterSet):
+class SiteFilter(CustomFieldFilterSet):
     id__in = NumericInFilter(
     id__in = NumericInFilter(
         field_name='id',
         field_name='id',
         lookup_expr='in'
         lookup_expr='in'
@@ -122,7 +123,7 @@ class RackRoleFilter(NameSlugSearchFilterSet):
         fields = ['name', 'slug', 'color']
         fields = ['name', 'slug', 'color']
 
 
 
 
-class RackFilter(CustomFieldFilterSet, django_filters.FilterSet):
+class RackFilter(CustomFieldFilterSet):
     id__in = NumericInFilter(
     id__in = NumericInFilter(
         field_name='id',
         field_name='id',
         lookup_expr='in'
         lookup_expr='in'
@@ -1065,3 +1066,81 @@ class InterfaceConnectionFilter(django_filters.FilterSet):
             Q(device__name__icontains=value) |
             Q(device__name__icontains=value) |
             Q(_connected_interface__device__name__icontains=value)
             Q(_connected_interface__device__name__icontains=value)
         )
         )
+
+
+class PowerPanelFilter(django_filters.FilterSet):
+    id__in = NumericInFilter(
+        field_name='id',
+        lookup_expr='in'
+    )
+    q = django_filters.CharFilter(
+        method='search',
+        label='Search',
+    )
+    site_id = django_filters.ModelMultipleChoiceFilter(
+        queryset=Site.objects.all(),
+        label='Site (ID)',
+    )
+    site = django_filters.ModelMultipleChoiceFilter(
+        field_name='site__slug',
+        queryset=Site.objects.all(),
+        to_field_name='slug',
+        label='Site name (slug)',
+    )
+    rack_group_id = django_filters.ModelMultipleChoiceFilter(
+        field_name='rack_group',
+        queryset=RackGroup.objects.all(),
+        label='Rack group (ID)',
+    )
+
+    class Meta:
+        model = PowerPanel
+        fields = ['name']
+
+    def search(self, queryset, name, value):
+        if not value.strip():
+            return queryset
+        qs_filter = (
+            Q(name__icontains=value)
+        )
+        return queryset.filter(qs_filter)
+
+
+class PowerFeedFilter(CustomFieldFilterSet):
+    id__in = NumericInFilter(
+        field_name='id',
+        lookup_expr='in'
+    )
+    q = django_filters.CharFilter(
+        method='search',
+        label='Search',
+    )
+    site_id = django_filters.ModelMultipleChoiceFilter(
+        field_name='power_panel__site',
+        queryset=Site.objects.all(),
+        label='Site (ID)',
+    )
+    site = django_filters.ModelMultipleChoiceFilter(
+        field_name='power_panel__site__slug',
+        queryset=Site.objects.all(),
+        to_field_name='slug',
+        label='Site name (slug)',
+    )
+    rack_id = django_filters.ModelMultipleChoiceFilter(
+        field_name='rack',
+        queryset=Rack.objects.all(),
+        label='Rack (ID)',
+    )
+
+    class Meta:
+        model = PowerFeed
+        fields = ['name', 'status', 'type', 'supply', 'phase']
+
+    def search(self, queryset, name, value):
+        if not value.strip():
+            return queryset
+        qs_filter = (
+            Q(name__icontains=value) |
+            Q(comments__icontains=value)
+        )
+        return queryset.filter(qs_filter)

+ 76 - 0
netbox/dcim/forms.py

@@ -3208,6 +3208,34 @@ class PowerPanelCSVForm(forms.ModelForm):
         fields = PowerPanel.csv_headers
         fields = PowerPanel.csv_headers
 
 
 
 
+class PowerPanelFilterForm(BootstrapMixin, CustomFieldFilterForm):
+    model = PowerPanel
+    q = forms.CharField(
+        required=False,
+        label='Search'
+    )
+    site = FilterChoiceField(
+        queryset=Site.objects.all(),
+        to_field_name='slug',
+        widget=APISelectMultiple(
+            api_url="/api/dcim/sites/",
+            value_field="slug",
+            filter_for={
+                'rack_id': 'site',
+            }
+        )
+    )
+    rack_group_id = FilterChoiceField(
+        queryset=RackGroup.objects.all(),
+        label='Rack group (ID)',
+        null_label='-- None --',
+        widget=APISelectMultiple(
+            api_url="/api/dcim/rack-groups/",
+            null_option=True,
+        )
+    )
+
+
 #
 #
 # Power feeds
 # Power feeds
 #
 #
@@ -3333,3 +3361,51 @@ class PowerFeedBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEd
         nullable_fields = [
         nullable_fields = [
             'rackgroup', 'comments',
             'rackgroup', 'comments',
         ]
         ]
+
+
+class PowerFeedFilterForm(BootstrapMixin, CustomFieldFilterForm):
+    model = PowerFeed
+    q = forms.CharField(
+        required=False,
+        label='Search'
+    )
+    site = FilterChoiceField(
+        queryset=Site.objects.all(),
+        to_field_name='slug',
+        widget=APISelectMultiple(
+            api_url="/api/dcim/sites/",
+            value_field="slug",
+            filter_for={
+                'rack_id': 'site',
+            }
+        )
+    )
+    rack_id = FilterChoiceField(
+        queryset=Rack.objects.all(),
+        label='Rack',
+        null_label='-- None --',
+        widget=APISelectMultiple(
+            api_url="/api/dcim/racks/",
+            null_option=True,
+        )
+    )
+    status = forms.MultipleChoiceField(
+        choices=POWERFEED_STATUS_CHOICES,
+        required=False,
+        widget=StaticSelect2Multiple()
+    )
+    type = forms.ChoiceField(
+        choices=add_blank_choice(POWERFEED_TYPE_CHOICES),
+        required=False,
+        widget=StaticSelect2()
+    )
+    supply = forms.ChoiceField(
+        choices=add_blank_choice(POWERFEED_SUPPLY_CHOICES),
+        required=False,
+        widget=StaticSelect2()
+    )
+    phase = forms.ChoiceField(
+        choices=add_blank_choice(POWERFEED_PHASE_CHOICES),
+        required=False,
+        widget=StaticSelect2()
+    )

+ 7 - 4
netbox/dcim/views.py

@@ -2129,6 +2129,8 @@ class PowerPanelListView(ObjectListView):
     ).annotate(
     ).annotate(
         powerfeed_count=Count('powerfeeds')
         powerfeed_count=Count('powerfeeds')
     )
     )
+    filter = filters.PowerPanelFilter
+    filter_form = forms.PowerPanelFilterForm
     table = tables.PowerPanelTable
     table = tables.PowerPanelTable
     template_name = 'dcim/powerpanel_list.html'
     template_name = 'dcim/powerpanel_list.html'
 
 
@@ -2175,6 +2177,7 @@ class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     ).annotate(
     ).annotate(
         rack_count=Count('powerfeeds')
         rack_count=Count('powerfeeds')
     )
     )
+    filter = filters.PowerPanelFilter
     table = tables.PowerPanelTable
     table = tables.PowerPanelTable
     default_return_url = 'dcim:powerpanel_list'
     default_return_url = 'dcim:powerpanel_list'
 
 
@@ -2187,8 +2190,8 @@ class PowerFeedListView(ObjectListView):
     queryset = PowerFeed.objects.select_related(
     queryset = PowerFeed.objects.select_related(
         'power_panel', 'rack'
         'power_panel', 'rack'
     )
     )
-    # filter = filters.PowerFeedFilter
-    # filter_form = forms.PowerFeedFilterForm
+    filter = filters.PowerFeedFilter
+    filter_form = forms.PowerFeedFilterForm
     table = tables.PowerFeedTable
     table = tables.PowerFeedTable
     template_name = 'dcim/powerfeed_list.html'
     template_name = 'dcim/powerfeed_list.html'
 
 
@@ -2232,7 +2235,7 @@ class PowerFeedBulkImportView(PermissionRequiredMixin, BulkImportView):
 class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
 class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
     permission_required = 'dcim.change_powerfeed'
     permission_required = 'dcim.change_powerfeed'
     queryset = PowerFeed.objects.select_related('power_panel', 'rack')
     queryset = PowerFeed.objects.select_related('power_panel', 'rack')
-    # filter = filters.PowerFeedFilter
+    filter = filters.PowerFeedFilter
     table = tables.PowerFeedTable
     table = tables.PowerFeedTable
     form = forms.PowerFeedBulkEditForm
     form = forms.PowerFeedBulkEditForm
     default_return_url = 'dcim:powerfeed_list'
     default_return_url = 'dcim:powerfeed_list'
@@ -2241,6 +2244,6 @@ class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
 class PowerFeedBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 class PowerFeedBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     permission_required = 'dcim.delete_powerfeed'
     permission_required = 'dcim.delete_powerfeed'
     queryset = PowerFeed.objects.select_related('power_panel', 'rack')
     queryset = PowerFeed.objects.select_related('power_panel', 'rack')
-    # filter = filters.PowerFeedFilter
+    filter = filters.PowerFeedFilter
     table = tables.PowerFeedTable
     table = tables.PowerFeedTable
     default_return_url = 'dcim:powerfeed_list'
     default_return_url = 'dcim:powerfeed_list'

+ 4 - 1
netbox/templates/dcim/powerpanel_list.html

@@ -11,8 +11,11 @@
 </div>
 </div>
 <h1>{% block title %}Power Panels{% endblock %}</h1>
 <h1>{% block title %}Power Panels{% endblock %}</h1>
 <div class="row">
 <div class="row">
-    <div class="col-md-12">
+    <div class="col-md-9">
         {% include 'utilities/obj_table.html' with bulk_delete_url='dcim:powerpanel_bulk_delete' %}
         {% include 'utilities/obj_table.html' with bulk_delete_url='dcim:powerpanel_bulk_delete' %}
     </div>
     </div>
+    <div class="col-md-3">
+		{% include 'inc/search_panel.html' %}
+    </div>
 </div>
 </div>
 {% endblock %}
 {% endblock %}