Browse Source

Converted DCIM object lists to ObjectListView

Jeremy Stretch 9 years ago
parent
commit
30cbbdeac8

+ 3 - 3
netbox/dcim/urls.py

@@ -7,7 +7,7 @@ from . import views
 urlpatterns = [
 
     # Sites
-    url(r'^sites/$', views.site_list, name='site_list'),
+    url(r'^sites/$', views.SiteListView.as_view(), name='site_list'),
     url(r'^sites/add/$', views.site_add, name='site_add'),
     url(r'^sites/import/$', views.SiteBulkImportView.as_view(), name='site_import'),
     url(r'^sites/(?P<slug>[\w-]+)/$', views.site, name='site'),
@@ -15,7 +15,7 @@ urlpatterns = [
     url(r'^sites/(?P<slug>[\w-]+)/delete/$', views.site_delete, name='site_delete'),
 
     # Racks
-    url(r'^racks/$', views.rack_list, name='rack_list'),
+    url(r'^racks/$', views.RackListView.as_view(), name='rack_list'),
     url(r'^racks/add/$', views.rack_add, name='rack_add'),
     url(r'^racks/import/$', views.RackBulkImportView.as_view(), name='rack_import'),
     url(r'^racks/edit/$', views.RackBulkEditView.as_view(), name='rack_bulk_edit'),
@@ -25,7 +25,7 @@ urlpatterns = [
     url(r'^racks/(?P<pk>\d+)/delete/$', views.rack_delete, name='rack_delete'),
 
     # Devices
-    url(r'^devices/$', views.device_list, name='device_list'),
+    url(r'^devices/$', views.DeviceListView.as_view(), name='device_list'),
     url(r'^devices/add/$', views.device_add, name='device_add'),
     url(r'^devices/import/$', views.DeviceBulkImportView.as_view(), name='device_import'),
     url(r'^devices/edit/$', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'),

+ 21 - 79
netbox/dcim/views.py

@@ -1,6 +1,5 @@
 import re
 
-from django.conf import settings
 from django.contrib import messages
 from django.contrib.auth.decorators import permission_required
 from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -10,14 +9,11 @@ from django.http import HttpResponseRedirect
 from django.shortcuts import get_object_or_404, redirect, render
 from django.utils.http import urlencode
 
-from django_tables2 import RequestConfig
-from extras.models import ExportTemplate
+from ipam.models import Prefix, IPAddress, VLAN
+from circuits.models import Circuit
 from utilities.error_handlers import handle_protectederror
 from utilities.forms import ConfirmationForm
-from utilities.paginator import EnhancedPaginator
 from utilities.views import ObjectListView, BulkImportView, BulkEditView, BulkDeleteView
-from ipam.models import Prefix, IPAddress, VLAN
-from circuits.models import Circuit
 
 from .filters import RackFilter, DeviceFilter, ConsoleConnectionFilter, PowerConnectionFilter, InterfaceConnectionFilter
 from .forms import SiteForm, SiteImportForm, RackForm, RackImportForm, RackBulkEditForm, RackBulkDeleteForm, \
@@ -64,25 +60,10 @@ def expand_pattern(string):
 # Sites
 #
 
-def site_list(request):
-
+class SiteListView(ObjectListView):
     queryset = Site.objects.all()
-
-    # Export
-    if 'export' in request.GET:
-        et = get_object_or_404(ExportTemplate, content_type__model='site', name=request.GET.get('export'))
-        response = et.to_response(context_dict={'queryset': queryset}, filename='netbox_sites')
-        return response
-
-    site_table = SiteTable(queryset)
-    RequestConfig(request, paginate={'per_page': settings.PAGINATE_COUNT, 'klass': EnhancedPaginator}).configure(site_table)
-
-    export_templates = ExportTemplate.objects.filter(content_type__model='site')
-
-    return render(request, 'dcim/site_list.html', {
-        'site_table': site_table,
-        'export_templates': export_templates,
-    })
+    table = SiteTable
+    template_name = 'dcim/site_list.html'
 
 
 def site(request, slug):
@@ -184,34 +165,14 @@ class SiteBulkImportView(PermissionRequiredMixin, BulkImportView):
 # Racks
 #
 
-def rack_list(request):
-
+class RackListView(ObjectListView):
     queryset = Rack.objects.select_related('site').annotate(device_count=Count('devices', distinct=True))
-    queryset = RackFilter(request.GET, queryset).qs
-
-    # Export
-    if 'export' in request.GET:
-        et = get_object_or_404(ExportTemplate, content_type__model='rack', name=request.GET.get('export'))
-        response = et.to_response(context_dict={'queryset': queryset}, filename='netbox_racks')
-        return response
-
-    # Hot-wire direct to rack view if only one rack was returned
-    if queryset.count() == 1:
-        return redirect('dcim:rack', pk=queryset[0].pk)
-
-    if request.user.has_perm('dcim.change_rack') or request.user.has_perm('dcim.delete_rack'):
-        rack_table = RackBulkEditTable(queryset)
-    else:
-        rack_table = RackTable(queryset)
-    RequestConfig(request, paginate={'per_page': settings.PAGINATE_COUNT, 'klass': EnhancedPaginator}).configure(rack_table)
-
-    export_templates = ExportTemplate.objects.filter(content_type__model='rack')
-
-    return render(request, 'dcim/rack_list.html', {
-        'rack_table': rack_table,
-        'export_templates': export_templates,
-        'filter_form': RackFilterForm(request.GET, label_suffix=''),
-    })
+    filter = RackFilter
+    filter_form = RackFilterForm
+    table = RackTable
+    edit_table = RackBulkEditTable
+    edit_table_permissions = ['dcim.change_rack', 'dcim.delete_rack']
+    template_name = 'dcim/rack_list.html'
 
 
 def rack(request, pk):
@@ -350,34 +311,15 @@ class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
 # Devices
 #
 
-def device_list(request):
-
-    queryset = Device.objects.select_related('device_type', 'device_type__manufacturer', 'device_role', 'rack', 'rack__site', 'primary_ip')
-    queryset = DeviceFilter(request.GET, queryset).qs
-
-    # Export
-    if 'export' in request.GET:
-        et = get_object_or_404(ExportTemplate, content_type__model='device', name=request.GET.get('export'))
-        response = et.to_response(context_dict={'queryset': queryset}, filename='netbox_devices')
-        return response
-
-    # Hot-wire direct to device view if only one device was returned
-    if queryset.count() == 1:
-        return redirect('dcim:device', pk=queryset[0].pk)
-
-    if request.user.has_perm('dcim.change_device') or request.user.has_perm('dcim.delete_device'):
-        device_table = DeviceBulkEditTable(queryset)
-    else:
-        device_table = DeviceTable(queryset)
-    RequestConfig(request, paginate={'per_page': settings.PAGINATE_COUNT, 'klass': EnhancedPaginator}).configure(device_table)
-
-    export_templates = ExportTemplate.objects.filter(content_type__model='device')
-
-    return render(request, 'dcim/device_list.html', {
-        'device_table': device_table,
-        'export_templates': export_templates,
-        'filter_form': DeviceFilterForm(request.GET, label_suffix=''),
-    })
+class DeviceListView(ObjectListView):
+    queryset = Device.objects.select_related('device_type', 'device_type__manufacturer', 'device_role', 'rack',
+                                             'rack__site', 'primary_ip')
+    filter = DeviceFilter
+    filter_form = DeviceFilterForm
+    table = DeviceTable
+    edit_table = DeviceBulkEditTable
+    edit_table_permissions = ['dcim.change_device', 'dcim.delete_device']
+    template_name = 'dcim/device_list.html'
 
 
 def device(request, pk):

+ 1 - 1
netbox/templates/dcim/device_list.html

@@ -32,7 +32,7 @@
 <h1>Devices</h1>
 <div class="row">
 	<div class="col-md-9">
-        {% include 'dcim/inc/device_table.html' with table=device_table %}
+        {% include 'dcim/inc/device_table.html' %}
     </div>
     <div class="col-md-3">
 		<div class="panel panel-default">

+ 1 - 1
netbox/templates/dcim/rack_list.html

@@ -32,7 +32,7 @@
 <h1>Racks</h1>
 <div class="row">
 	<div class="col-md-9">
-        {% include 'dcim/inc/rack_table.html' with table=rack_table %}
+        {% include 'dcim/inc/rack_table.html' %}
     </div>
     <div class="col-md-3">
 		<div class="panel panel-default">

+ 1 - 1
netbox/templates/dcim/site_list.html

@@ -26,5 +26,5 @@
     {% endif %}
 </div>
 <h1>Sites</h1>
-{% render_table site_table 'table.html' %}
+{% render_table table 'table.html' %}
 {% endblock %}

+ 18 - 3
netbox/utilities/views.py

@@ -2,11 +2,12 @@ from django.conf import settings
 from django.contrib import messages
 from django.contrib.admin.views.decorators import staff_member_required
 from django.contrib.contenttypes.models import ContentType
-from django.template import TemplateSyntaxError
 from django.core.urlresolvers import reverse
 from django.db import transaction, IntegrityError
 from django.db.models import ProtectedError
+from django.http import HttpResponseRedirect
 from django.shortcuts import get_object_or_404, redirect, render
+from django.template import TemplateSyntaxError
 from django.utils.decorators import method_decorator
 from django.views.generic import View
 
@@ -22,7 +23,10 @@ class ObjectListView(View):
     filter = None
     filter_form = None
     table = None
+    edit_table = None
+    edit_table_permissions = []
     template_name = None
+    redirect_on_single_result = True
 
     def get(self, request, *args, **kwargs):
 
@@ -31,7 +35,7 @@ class ObjectListView(View):
         if self.filter:
             self.queryset = self.filter(request.GET, self.queryset).qs
 
-        # Export
+        # Check for export template rendering
         if request.GET.get('export'):
             et = get_object_or_404(ExportTemplate, content_type=object_ct, name=request.GET.get('export'))
             try:
@@ -41,7 +45,18 @@ class ObjectListView(View):
             except TemplateSyntaxError:
                 messages.error(request, "There was an error rendering the selected export template ({}).".format(et.name))
 
-        table = self.table(self.queryset)
+        # Attempt to redirect automatically if the query returns a single result
+        if self.redirect_on_single_result and self.queryset.count() == 1:
+            try:
+                return HttpResponseRedirect(self.queryset[0].get_absolute_url())
+            except AttributeError:
+                pass
+
+        # Construct the table based on the user's permissions
+        if any([request.user.has_perm(perm) for perm in self.edit_table_permissions]):
+            table = self.edit_table(self.queryset)
+        else:
+            table = self.table(self.queryset)
         RequestConfig(request, paginate={'per_page': settings.PAGINATE_COUNT, 'klass': EnhancedPaginator})\
             .configure(table)