From 30cbbdeac8be50add8c4ccbc132b6089f4ec3c10 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 4 Mar 2016 10:35:39 -0500 Subject: [PATCH] Converted DCIM object lists to ObjectListView --- netbox/dcim/urls.py | 6 +- netbox/dcim/views.py | 102 ++++++------------------- netbox/templates/dcim/device_list.html | 2 +- netbox/templates/dcim/rack_list.html | 2 +- netbox/templates/dcim/site_list.html | 2 +- netbox/utilities/views.py | 21 ++++- 6 files changed, 46 insertions(+), 89 deletions(-) diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index 5e79c634c..d0f1bfec0 100644 --- a/netbox/dcim/urls.py +++ b/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[\w-]+)/$', views.site, name='site'), @@ -15,7 +15,7 @@ urlpatterns = [ url(r'^sites/(?P[\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\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'), diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 6e9781b21..61cc37049 100644 --- a/netbox/dcim/views.py +++ b/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 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 utilities.error_handlers import handle_protectederror +from utilities.forms import ConfirmationForm +from utilities.views import ObjectListView, BulkImportView, BulkEditView, BulkDeleteView 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): diff --git a/netbox/templates/dcim/device_list.html b/netbox/templates/dcim/device_list.html index 2fe237f83..ee629e7af 100644 --- a/netbox/templates/dcim/device_list.html +++ b/netbox/templates/dcim/device_list.html @@ -32,7 +32,7 @@

Devices

- {% include 'dcim/inc/device_table.html' with table=device_table %} + {% include 'dcim/inc/device_table.html' %}
diff --git a/netbox/templates/dcim/rack_list.html b/netbox/templates/dcim/rack_list.html index c905258c7..a80e40fd2 100644 --- a/netbox/templates/dcim/rack_list.html +++ b/netbox/templates/dcim/rack_list.html @@ -32,7 +32,7 @@

Racks

- {% include 'dcim/inc/rack_table.html' with table=rack_table %} + {% include 'dcim/inc/rack_table.html' %}
diff --git a/netbox/templates/dcim/site_list.html b/netbox/templates/dcim/site_list.html index 629d313f2..d0b163bb6 100644 --- a/netbox/templates/dcim/site_list.html +++ b/netbox/templates/dcim/site_list.html @@ -26,5 +26,5 @@ {% endif %}

Sites

-{% render_table site_table 'table.html' %} +{% render_table table 'table.html' %} {% endblock %} diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index e5b145075..8bd14ca28 100644 --- a/netbox/utilities/views.py +++ b/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)