diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index f487759a7..52eeb7f3a 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -991,7 +991,7 @@ class ConsolePort(models.Model): def __unicode__(self): return self.name - def get_absolute_url(self): + def get_parent_url(self): return self.device.get_absolute_url() # Used for connections export @@ -1035,7 +1035,7 @@ class ConsoleServerPort(models.Model): def __unicode__(self): return self.name - def get_absolute_url(self): + def get_parent_url(self): return self.device.get_absolute_url() @@ -1056,7 +1056,7 @@ class PowerPort(models.Model): def __unicode__(self): return self.name - def get_absolute_url(self): + def get_parent_url(self): return self.device.get_absolute_url() # Used for connections export @@ -1094,7 +1094,7 @@ class PowerOutlet(models.Model): def __unicode__(self): return self.name - def get_absolute_url(self): + def get_parent_url(self): return self.device.get_absolute_url() @@ -1133,7 +1133,7 @@ class Interface(models.Model): def __unicode__(self): return self.name - def get_absolute_url(self): + def get_parent_url(self): return self.device.get_absolute_url() def clean(self): @@ -1224,7 +1224,7 @@ class DeviceBay(models.Model): def __unicode__(self): return u'{} - {}'.format(self.device.name, self.name) - def get_absolute_url(self): + def get_parent_url(self): return self.device.get_absolute_url() def clean(self): @@ -1261,5 +1261,5 @@ class Module(models.Model): def __unicode__(self): return self.name - def get_absolute_url(self): + def get_parent_url(self): return reverse('dcim:device_inventory', args=[self.device.pk]) diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index 0b3714159..180689126 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -111,7 +111,7 @@ urlpatterns = [ url(r'^console-ports/(?P\d+)/connect/$', views.consoleport_connect, name='consoleport_connect'), url(r'^console-ports/(?P\d+)/disconnect/$', views.consoleport_disconnect, name='consoleport_disconnect'), url(r'^console-ports/(?P\d+)/edit/$', views.ConsolePortEditView.as_view(), name='consoleport_edit'), - url(r'^console-ports/(?P\d+)/delete/$', views.consoleport_delete, name='consoleport_delete'), + url(r'^console-ports/(?P\d+)/delete/$', views.ConsolePortDeleteView.as_view(), name='consoleport_delete'), # Console server ports url(r'^devices/(?P\d+)/console-server-ports/add/$', views.consoleserverport_add, name='consoleserverport_add'), @@ -119,7 +119,7 @@ urlpatterns = [ url(r'^console-server-ports/(?P\d+)/connect/$', views.consoleserverport_connect, name='consoleserverport_connect'), url(r'^console-server-ports/(?P\d+)/disconnect/$', views.consoleserverport_disconnect, name='consoleserverport_disconnect'), url(r'^console-server-ports/(?P\d+)/edit/$', views.ConsoleServerPortEditView.as_view(), name='consoleserverport_edit'), - url(r'^console-server-ports/(?P\d+)/delete/$', views.consoleserverport_delete, name='consoleserverport_delete'), + url(r'^console-server-ports/(?P\d+)/delete/$', views.ConsoleServerPortDeleteView.as_view(), name='consoleserverport_delete'), # Power ports url(r'^devices/(?P\d+)/power-ports/add/$', views.powerport_add, name='powerport_add'), @@ -127,7 +127,7 @@ urlpatterns = [ url(r'^power-ports/(?P\d+)/connect/$', views.powerport_connect, name='powerport_connect'), url(r'^power-ports/(?P\d+)/disconnect/$', views.powerport_disconnect, name='powerport_disconnect'), url(r'^power-ports/(?P\d+)/edit/$', views.PowerPortEditView.as_view(), name='powerport_edit'), - url(r'^power-ports/(?P\d+)/delete/$', views.powerport_delete, name='powerport_delete'), + url(r'^power-ports/(?P\d+)/delete/$', views.PowerPortDeleteView.as_view(), name='powerport_delete'), # Power outlets url(r'^devices/(?P\d+)/power-outlets/add/$', views.poweroutlet_add, name='poweroutlet_add'), @@ -135,13 +135,13 @@ urlpatterns = [ url(r'^power-outlets/(?P\d+)/connect/$', views.poweroutlet_connect, name='poweroutlet_connect'), url(r'^power-outlets/(?P\d+)/disconnect/$', views.poweroutlet_disconnect, name='poweroutlet_disconnect'), url(r'^power-outlets/(?P\d+)/edit/$', views.PowerOutletEditView.as_view(), name='poweroutlet_edit'), - url(r'^power-outlets/(?P\d+)/delete/$', views.poweroutlet_delete, name='poweroutlet_delete'), + url(r'^power-outlets/(?P\d+)/delete/$', views.PowerOutletDeleteView.as_view(), name='poweroutlet_delete'), # Device bays url(r'^devices/(?P\d+)/bays/add/$', views.devicebay_add, name='devicebay_add'), url(r'^devices/(?P\d+)/bays/delete/$', views.DeviceBayBulkDeleteView.as_view(), name='devicebay_bulk_delete'), url(r'^device-bays/(?P\d+)/edit/$', views.DeviceBayEditView.as_view(), name='devicebay_edit'), - url(r'^device-bays/(?P\d+)/delete/$', views.devicebay_delete, name='devicebay_delete'), + url(r'^device-bays/(?P\d+)/delete/$', views.DeviceBayDeleteView.as_view(), name='devicebay_delete'), url(r'^device-bays/(?P\d+)/populate/$', views.devicebay_populate, name='devicebay_populate'), url(r'^device-bays/(?P\d+)/depopulate/$', views.devicebay_depopulate, name='devicebay_depopulate'), @@ -161,11 +161,11 @@ urlpatterns = [ url(r'^devices/(?P\d+)/interface-connections/add/$', views.interfaceconnection_add, name='interfaceconnection_add'), url(r'^interface-connections/(?P\d+)/delete/$', views.interfaceconnection_delete, name='interfaceconnection_delete'), url(r'^interfaces/(?P\d+)/edit/$', views.InterfaceEditView.as_view(), name='interface_edit'), - url(r'^interfaces/(?P\d+)/delete/$', views.interface_delete, name='interface_delete'), + url(r'^interfaces/(?P\d+)/delete/$', views.InterfaceDeleteView.as_view(), name='interface_delete'), # Modules url(r'^devices/(?P\d+)/modules/add/$', views.module_add, name='module_add'), url(r'^modules/(?P\d+)/edit/$', views.ModuleEditView.as_view(), name='module_edit'), - url(r'^modules/(?P\d+)/delete/$', views.module_delete, name='module_delete'), + url(r'^modules/(?P\d+)/delete/$', views.ModuleDeleteView.as_view(), name='module_delete'), ] diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 1577edb84..354855d44 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -795,27 +795,9 @@ class ConsolePortEditView(PermissionRequiredMixin, ObjectEditView): form_class = forms.ConsolePortForm -@permission_required('dcim.delete_consoleport') -def consoleport_delete(request, pk): - - consoleport = get_object_or_404(ConsolePort, pk=pk) - - if request.method == 'POST': - form = ConfirmationForm(request.POST) - if form.is_valid(): - consoleport.delete() - messages.success(request, "Console port {0} has been deleted from {1}".format(consoleport, - consoleport.device)) - return redirect('dcim:device', pk=consoleport.device.pk) - - else: - form = ConfirmationForm() - - return render(request, 'dcim/consoleport_delete.html', { - 'consoleport': consoleport, - 'form': form, - 'cancel_url': reverse('dcim:device', kwargs={'pk': consoleport.device.pk}), - }) +class ConsolePortDeleteView(PermissionRequiredMixin, ObjectDeleteView): + permission_required = 'dcim.delete_consoleport' + model = ConsolePort class ConsolePortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): @@ -941,27 +923,9 @@ class ConsoleServerPortEditView(PermissionRequiredMixin, ObjectEditView): form_class = forms.ConsoleServerPortForm -@permission_required('dcim.delete_consoleserverport') -def consoleserverport_delete(request, pk): - - consoleserverport = get_object_or_404(ConsoleServerPort, pk=pk) - - if request.method == 'POST': - form = ConfirmationForm(request.POST) - if form.is_valid(): - consoleserverport.delete() - messages.success(request, "Console server port {0} has been deleted from {1}" - .format(consoleserverport, consoleserverport.device)) - return redirect('dcim:device', pk=consoleserverport.device.pk) - - else: - form = ConfirmationForm() - - return render(request, 'dcim/consoleserverport_delete.html', { - 'consoleserverport': consoleserverport, - 'form': form, - 'cancel_url': reverse('dcim:device', kwargs={'pk': consoleserverport.device.pk}), - }) +class ConsoleServerPortDeleteView(PermissionRequiredMixin, ObjectDeleteView): + permission_required = 'dcim.delete_consoleserverport' + model = ConsoleServerPort class ConsoleServerPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): @@ -1078,26 +1042,9 @@ class PowerPortEditView(PermissionRequiredMixin, ObjectEditView): form_class = forms.PowerPortForm -@permission_required('dcim.delete_powerport') -def powerport_delete(request, pk): - - powerport = get_object_or_404(PowerPort, pk=pk) - - if request.method == 'POST': - form = ConfirmationForm(request.POST) - if form.is_valid(): - powerport.delete() - messages.success(request, "Power port {0} has been deleted from {1}".format(powerport, powerport.device)) - return redirect('dcim:device', pk=powerport.device.pk) - - else: - form = ConfirmationForm() - - return render(request, 'dcim/powerport_delete.html', { - 'powerport': powerport, - 'form': form, - 'cancel_url': reverse('dcim:device', kwargs={'pk': powerport.device.pk}), - }) +class PowerPortDeleteView(PermissionRequiredMixin, ObjectDeleteView): + permission_required = 'dcim.delete_powerport' + model = PowerPort class PowerPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): @@ -1221,27 +1168,9 @@ class PowerOutletEditView(PermissionRequiredMixin, ObjectEditView): form_class = forms.PowerOutletForm -@permission_required('dcim.delete_poweroutlet') -def poweroutlet_delete(request, pk): - - poweroutlet = get_object_or_404(PowerOutlet, pk=pk) - - if request.method == 'POST': - form = ConfirmationForm(request.POST) - if form.is_valid(): - poweroutlet.delete() - messages.success(request, "Power outlet {0} has been deleted from {1}".format(poweroutlet, - poweroutlet.device)) - return redirect('dcim:device', pk=poweroutlet.device.pk) - - else: - form = ConfirmationForm() - - return render(request, 'dcim/poweroutlet_delete.html', { - 'poweroutlet': poweroutlet, - 'form': form, - 'cancel_url': reverse('dcim:device', kwargs={'pk': poweroutlet.device.pk}), - }) +class PowerOutletDeleteView(PermissionRequiredMixin, ObjectDeleteView): + permission_required = 'dcim.delete_poweroutlet' + model = PowerOutlet class PowerOutletBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): @@ -1303,26 +1232,9 @@ class InterfaceEditView(PermissionRequiredMixin, ObjectEditView): form_class = forms.InterfaceForm -@permission_required('dcim.delete_interface') -def interface_delete(request, pk): - - interface = get_object_or_404(Interface, pk=pk) - - if request.method == 'POST': - form = ConfirmationForm(request.POST) - if form.is_valid(): - interface.delete() - messages.success(request, "Interface {0} has been deleted from {1}".format(interface, interface.device)) - return redirect('dcim:device', pk=interface.device.pk) - - else: - form = ConfirmationForm() - - return render(request, 'dcim/interface_delete.html', { - 'interface': interface, - 'form': form, - 'cancel_url': reverse('dcim:device', kwargs={'pk': interface.device.pk}), - }) +class InterfaceDeleteView(PermissionRequiredMixin, ObjectDeleteView): + permission_required = 'dcim.delete_interface' + model = Interface class InterfaceBulkAddView(PermissionRequiredMixin, BulkEditView): @@ -1422,26 +1334,9 @@ class DeviceBayEditView(PermissionRequiredMixin, ObjectEditView): form_class = forms.DeviceBayForm -@permission_required('dcim.delete_devicebay') -def devicebay_delete(request, pk): - - devicebay = get_object_or_404(DeviceBay, pk=pk) - - if request.method == 'POST': - form = ConfirmationForm(request.POST) - if form.is_valid(): - devicebay.delete() - messages.success(request, "Device bay {} has been deleted from {}".format(devicebay, devicebay.device)) - return redirect('dcim:device', pk=devicebay.device.pk) - - else: - form = ConfirmationForm() - - return render(request, 'dcim/devicebay_delete.html', { - 'devicebay': devicebay, - 'form': form, - 'cancel_url': reverse('dcim:device', kwargs={'pk': devicebay.device.pk}), - }) +class DeviceBayDeleteView(PermissionRequiredMixin, ObjectDeleteView): + permission_required = 'dcim.delete_devicebay' + model = DeviceBay @permission_required('dcim.change_devicebay') @@ -1699,23 +1594,6 @@ class ModuleEditView(PermissionRequiredMixin, ObjectEditView): form_class = forms.ModuleForm -@permission_required('dcim.delete_module') -def module_delete(request, pk): - - module = get_object_or_404(Module, pk=pk) - - if request.method == 'POST': - form = ConfirmationForm(request.POST) - if form.is_valid(): - module.delete() - messages.success(request, "Module {} has been deleted from {}".format(module, module.device)) - return redirect('dcim:device_inventory', pk=module.device.pk) - - else: - form = ConfirmationForm() - - return render(request, 'dcim/module_delete.html', { - 'module': module, - 'form': form, - 'cancel_url': reverse('dcim:device_inventory', kwargs={'pk': module.device.pk}), - }) +class ModuleDeleteView(PermissionRequiredMixin, ObjectDeleteView): + permission_required = 'dcim.delete_module' + model = Module diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index 7b47e76e1..8606a9bb6 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -129,6 +129,13 @@ class ObjectEditView(View): else: return get_object_or_404(self.model, pk=kwargs['pk']) + def get_cancel_url(self, obj): + if hasattr(obj, 'get_absolute_url'): + return obj.get_absolute_url() + if hasattr(obj, 'get_parent_url'): + return obj.get_parent_url() + return reverse(self.cancel_url) + def get(self, request, *args, **kwargs): if kwargs: @@ -142,7 +149,7 @@ class ObjectEditView(View): 'obj': obj, 'obj_type': self.model._meta.verbose_name, 'form': form, - 'cancel_url': obj.get_absolute_url() if hasattr(obj, 'get_absolute_url') else reverse(self.cancel_url), + 'cancel_url': self.get_cancel_url(obj), }) def post(self, request, *args, **kwargs): @@ -174,14 +181,16 @@ class ObjectEditView(View): return redirect(request.path) elif self.success_url: return redirect(self.success_url) - else: + elif hasattr(obj, 'get_absolute_url'): return redirect(obj.get_absolute_url()) + elif hasattr(obj, 'get_parent_url'): + return redirect(obj.get_parent_url()) return render(request, self.template_name, { 'obj': obj, 'obj_type': self.model._meta.verbose_name, 'form': form, - 'cancel_url': obj.get_absolute_url() if hasattr(obj, 'get_absolute_url') else reverse(self.cancel_url), + 'cancel_url': self.get_cancel_url(obj), }) @@ -197,6 +206,13 @@ class ObjectDeleteView(View): else: return get_object_or_404(self.model, pk=kwargs['pk']) + def get_cancel_url(self, obj): + if hasattr(obj, 'get_absolute_url'): + return obj.get_absolute_url() + if hasattr(obj, 'get_parent_url'): + return obj.get_parent_url() + return reverse('home') + def get(self, request, *args, **kwargs): obj = self.get_object(kwargs) @@ -206,7 +222,7 @@ class ObjectDeleteView(View): 'obj': obj, 'form': form, 'obj_type': self.model._meta.verbose_name, - 'cancel_url': obj.get_absolute_url(), + 'cancel_url': self.get_cancel_url(obj), }) def post(self, request, *args, **kwargs): @@ -216,19 +232,24 @@ class ObjectDeleteView(View): if form.is_valid(): try: obj.delete() - msg = u'Deleted {} {}'.format(self.model._meta.verbose_name, obj) - messages.success(request, msg) - UserAction.objects.log_delete(request.user, obj, msg) - return redirect(self.redirect_url) except ProtectedError, e: handle_protectederror(obj, request, e) return redirect(obj.get_absolute_url()) + msg = u'Deleted {} {}'.format(self.model._meta.verbose_name, obj) + messages.success(request, msg) + UserAction.objects.log_delete(request.user, obj, msg) + if self.redirect_url: + return redirect(self.redirect_url) + elif hasattr(obj, 'get_parent_url'): + return redirect(obj.get_parent_url()) + else: + return redirect('home') return render(request, self.template_name, { 'obj': obj, 'form': form, 'obj_type': self.model._meta.verbose_name, - 'cancel_url': obj.get_absolute_url(), + 'cancel_url': self.get_cancel_url(obj), })