Browse Source

Fixes #4: Include filter params when redirecting user after bulk edit/delete

Jeremy Stretch 9 years ago
parent
commit
8e11a3d624

+ 4 - 4
netbox/circuits/views.py

@@ -122,7 +122,7 @@ class ProviderBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = Provider
     cls = Provider
     form = ProviderBulkEditForm
     form = ProviderBulkEditForm
     template_name = 'circuits/provider_bulk_edit.html'
     template_name = 'circuits/provider_bulk_edit.html'
-    redirect_url = 'circuits:provider_list'
+    default_redirect_url = 'circuits:provider_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -140,7 +140,7 @@ class ProviderBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = Provider
     cls = Provider
     form = ProviderBulkDeleteForm
     form = ProviderBulkDeleteForm
     template_name = 'circuits/provider_bulk_delete.html'
     template_name = 'circuits/provider_bulk_delete.html'
-    redirect_url = 'circuits:provider_list'
+    default_redirect_url = 'circuits:provider_list'
 
 
 
 
 #
 #
@@ -251,7 +251,7 @@ class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = Circuit
     cls = Circuit
     form = CircuitBulkEditForm
     form = CircuitBulkEditForm
     template_name = 'circuits/circuit_bulk_edit.html'
     template_name = 'circuits/circuit_bulk_edit.html'
-    redirect_url = 'circuits:circuit_list'
+    default_redirect_url = 'circuits:circuit_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -269,4 +269,4 @@ class CircuitBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = Circuit
     cls = Circuit
     form = CircuitBulkDeleteForm
     form = CircuitBulkDeleteForm
     template_name = 'circuits/circuit_bulk_delete.html'
     template_name = 'circuits/circuit_bulk_delete.html'
-    redirect_url = 'circuits:circuit_list'
+    default_redirect_url = 'circuits:circuit_list'

+ 8 - 8
netbox/dcim/views.py

@@ -210,7 +210,7 @@ class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = RackGroup
     cls = RackGroup
     form = RackGroupBulkDeleteForm
     form = RackGroupBulkDeleteForm
     template_name = 'dcim/rackgroup_bulk_delete.html'
     template_name = 'dcim/rackgroup_bulk_delete.html'
-    redirect_url = 'dcim:rackgroup_list'
+    default_redirect_url = 'dcim:rackgroup_list'
 
 
 
 
 #
 #
@@ -338,7 +338,7 @@ class RackBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = Rack
     cls = Rack
     form = RackBulkEditForm
     form = RackBulkEditForm
     template_name = 'dcim/rack_bulk_edit.html'
     template_name = 'dcim/rack_bulk_edit.html'
-    redirect_url = 'dcim:rack_list'
+    default_redirect_url = 'dcim:rack_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -356,7 +356,7 @@ class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = Rack
     cls = Rack
     form = RackBulkDeleteForm
     form = RackBulkDeleteForm
     template_name = 'dcim/rack_bulk_delete.html'
     template_name = 'dcim/rack_bulk_delete.html'
-    redirect_url = 'dcim:rack_list'
+    default_redirect_url = 'dcim:rack_list'
 
 
 
 
 #
 #
@@ -476,7 +476,7 @@ class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = DeviceType
     cls = DeviceType
     form = DeviceTypeBulkEditForm
     form = DeviceTypeBulkEditForm
     template_name = 'dcim/devicetype_bulk_edit.html'
     template_name = 'dcim/devicetype_bulk_edit.html'
-    redirect_url = 'dcim:devicetype_list'
+    default_redirect_url = 'dcim:devicetype_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -494,7 +494,7 @@ class DeviceTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = DeviceType
     cls = DeviceType
     form = DeviceTypeBulkDeleteForm
     form = DeviceTypeBulkDeleteForm
     template_name = 'dcim/devicetype_bulk_delete.html'
     template_name = 'dcim/devicetype_bulk_delete.html'
-    redirect_url = 'dcim:devicetype_list'
+    default_redirect_url = 'dcim:devicetype_list'
 
 
 
 
 #
 #
@@ -771,7 +771,7 @@ class DeviceBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = Device
     cls = Device
     form = DeviceBulkEditForm
     form = DeviceBulkEditForm
     template_name = 'dcim/device_bulk_edit.html'
     template_name = 'dcim/device_bulk_edit.html'
-    redirect_url = 'dcim:device_list'
+    default_redirect_url = 'dcim:device_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -796,7 +796,7 @@ class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = Device
     cls = Device
     form = DeviceBulkDeleteForm
     form = DeviceBulkDeleteForm
     template_name = 'dcim/device_bulk_delete.html'
     template_name = 'dcim/device_bulk_delete.html'
-    redirect_url = 'dcim:device_list'
+    default_redirect_url = 'dcim:device_list'
 
 
 
 
 def device_inventory(request, pk):
 def device_inventory(request, pk):
@@ -1508,7 +1508,7 @@ class InterfaceBulkAddView(PermissionRequiredMixin, BulkEditView):
     cls = Device
     cls = Device
     form = InterfaceBulkCreateForm
     form = InterfaceBulkCreateForm
     template_name = 'dcim/interface_bulk_add.html'
     template_name = 'dcim/interface_bulk_add.html'
-    redirect_url = 'dcim:device_list'
+    default_redirect_url = 'dcim:device_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 

+ 10 - 10
netbox/ipam/views.py

@@ -152,7 +152,7 @@ class VRFBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = VRF
     cls = VRF
     form = VRFBulkEditForm
     form = VRFBulkEditForm
     template_name = 'ipam/vrf_bulk_edit.html'
     template_name = 'ipam/vrf_bulk_edit.html'
-    redirect_url = 'ipam:vrf_list'
+    default_redirect_url = 'ipam:vrf_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -170,7 +170,7 @@ class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = VRF
     cls = VRF
     form = VRFBulkDeleteForm
     form = VRFBulkDeleteForm
     template_name = 'ipam/vrf_bulk_delete.html'
     template_name = 'ipam/vrf_bulk_delete.html'
-    redirect_url = 'ipam:vrf_list'
+    default_redirect_url = 'ipam:vrf_list'
 
 
 
 
 #
 #
@@ -294,7 +294,7 @@ class AggregateBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = Aggregate
     cls = Aggregate
     form = AggregateBulkEditForm
     form = AggregateBulkEditForm
     template_name = 'ipam/aggregate_bulk_edit.html'
     template_name = 'ipam/aggregate_bulk_edit.html'
-    redirect_url = 'ipam:aggregate_list'
+    default_redirect_url = 'ipam:aggregate_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -312,7 +312,7 @@ class AggregateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = Aggregate
     cls = Aggregate
     form = AggregateBulkDeleteForm
     form = AggregateBulkDeleteForm
     template_name = 'ipam/aggregate_bulk_delete.html'
     template_name = 'ipam/aggregate_bulk_delete.html'
-    redirect_url = 'ipam:aggregate_list'
+    default_redirect_url = 'ipam:aggregate_list'
 
 
 
 
 #
 #
@@ -465,7 +465,7 @@ class PrefixBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = Prefix
     cls = Prefix
     form = PrefixBulkEditForm
     form = PrefixBulkEditForm
     template_name = 'ipam/prefix_bulk_edit.html'
     template_name = 'ipam/prefix_bulk_edit.html'
-    redirect_url = 'ipam:prefix_list'
+    default_redirect_url = 'ipam:prefix_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -487,7 +487,7 @@ class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = Prefix
     cls = Prefix
     form = PrefixBulkDeleteForm
     form = PrefixBulkDeleteForm
     template_name = 'ipam/prefix_bulk_delete.html'
     template_name = 'ipam/prefix_bulk_delete.html'
-    redirect_url = 'ipam:prefix_list'
+    default_redirect_url = 'ipam:prefix_list'
 
 
 
 
 def prefix_ipaddresses(request, pk):
 def prefix_ipaddresses(request, pk):
@@ -646,7 +646,7 @@ class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = IPAddress
     cls = IPAddress
     form = IPAddressBulkEditForm
     form = IPAddressBulkEditForm
     template_name = 'ipam/ipaddress_bulk_edit.html'
     template_name = 'ipam/ipaddress_bulk_edit.html'
-    redirect_url = 'ipam:ipaddress_list'
+    default_redirect_url = 'ipam:ipaddress_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -668,7 +668,7 @@ class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = IPAddress
     cls = IPAddress
     form = IPAddressBulkDeleteForm
     form = IPAddressBulkDeleteForm
     template_name = 'ipam/ipaddress_bulk_delete.html'
     template_name = 'ipam/ipaddress_bulk_delete.html'
-    redirect_url = 'ipam:ipaddress_list'
+    default_redirect_url = 'ipam:ipaddress_list'
 
 
 
 
 #
 #
@@ -783,7 +783,7 @@ class VLANBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = VLAN
     cls = VLAN
     form = VLANBulkEditForm
     form = VLANBulkEditForm
     template_name = 'ipam/vlan_bulk_edit.html'
     template_name = 'ipam/vlan_bulk_edit.html'
-    redirect_url = 'ipam:vlan_list'
+    default_redirect_url = 'ipam:vlan_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -801,4 +801,4 @@ class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = VLAN
     cls = VLAN
     form = VLANBulkDeleteForm
     form = VLANBulkDeleteForm
     template_name = 'ipam/vlan_bulk_delete.html'
     template_name = 'ipam/vlan_bulk_delete.html'
-    redirect_url = 'ipam:vlan_list'
+    default_redirect_url = 'ipam:vlan_list'

+ 2 - 2
netbox/secrets/views.py

@@ -203,7 +203,7 @@ class SecretBulkEditView(PermissionRequiredMixin, BulkEditView):
     cls = Secret
     cls = Secret
     form = SecretBulkEditForm
     form = SecretBulkEditForm
     template_name = 'secrets/secret_bulk_edit.html'
     template_name = 'secrets/secret_bulk_edit.html'
-    redirect_url = 'secrets:secret_list'
+    default_redirect_url = 'secrets:secret_list'
 
 
     def update_objects(self, pk_list, form):
     def update_objects(self, pk_list, form):
 
 
@@ -221,4 +221,4 @@ class SecretBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     cls = Secret
     cls = Secret
     form = SecretBulkDeleteForm
     form = SecretBulkDeleteForm
     template_name = 'secrets/secret_bulk_delete.html'
     template_name = 'secrets/secret_bulk_delete.html'
-    redirect_url = 'secrets:secret_list'
+    default_redirect_url = 'secrets:secret_list'

+ 1 - 0
netbox/templates/circuits/inc/circuit_table.html

@@ -2,6 +2,7 @@
 {% if perms.circuits.change_circuit or perms.circuits.delete_circuit %}
 {% if perms.circuits.change_circuit or perms.circuits.delete_circuit %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.circuits.change_circuit %}
         {% if perms.circuits.change_circuit %}
             <button type="submit" name="_edit" formaction="{% url 'circuits:circuit_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'circuits:circuit_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/circuits/inc/provider_table.html

@@ -2,6 +2,7 @@
 {% if perms.circuits.change_provider or perms.circuits.delete_provider %}
 {% if perms.circuits.change_provider or perms.circuits.delete_provider %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.circuits.change_provider %}
         {% if perms.circuits.change_provider %}
             <button type="submit" name="_edit" formaction="{% url 'circuits:provider_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'circuits:provider_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/dcim/inc/device_table.html

@@ -2,6 +2,7 @@
 {% if perms.dcim.add_interface or perms.dcim.change_device or perms.dcim.delete_device %}
 {% if perms.dcim.add_interface or perms.dcim.change_device or perms.dcim.delete_device %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.dcim.add_interface %}
         {% if perms.dcim.add_interface %}
             <button type="submit" name="_addinterfaces" formaction="{% url 'dcim:interface_bulk_add' %}" class="btn btn-primary btn-sm">
             <button type="submit" name="_addinterfaces" formaction="{% url 'dcim:interface_bulk_add' %}" class="btn btn-primary btn-sm">

+ 1 - 0
netbox/templates/dcim/inc/devicetype_table.html

@@ -2,6 +2,7 @@
 {% if perms.dcim.change_devicetype or perms.dcim.delete_devicetype %}
 {% if perms.dcim.change_devicetype or perms.dcim.delete_devicetype %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.dcim.change_devicetype %}
         {% if perms.dcim.change_devicetype %}
             <button type="submit" name="_edit" formaction="{% url 'dcim:devicetype_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'dcim:devicetype_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/dcim/inc/rack_table.html

@@ -2,6 +2,7 @@
 {% if perms.dcim.change_rack or perms.dcim.delete_rack %}
 {% if perms.dcim.change_rack or perms.dcim.delete_rack %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.dcim.change_rack %}
         {% if perms.dcim.change_rack %}
             <button type="submit" name="_edit" formaction="{% url 'dcim:rack_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'dcim:rack_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/dcim/inc/rackgroup_table.html

@@ -2,6 +2,7 @@
 {% if perms.dcim.delete_rackgroup %}
 {% if perms.dcim.delete_rackgroup %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         <button type="submit" name="_delete" formaction="{% url 'dcim:rackgroup_bulk_delete' %}" class="btn btn-danger btn-sm">
         <button type="submit" name="_delete" formaction="{% url 'dcim:rackgroup_bulk_delete' %}" class="btn btn-danger btn-sm">
             <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
             <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>

+ 1 - 0
netbox/templates/ipam/inc/aggregate_table.html

@@ -2,6 +2,7 @@
 {% if perms.ipam.change_aggregate or perms.ipam.delete_aggregate %}
 {% if perms.ipam.change_aggregate or perms.ipam.delete_aggregate %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.ipam.change_aggregate %}
         {% if perms.ipam.change_aggregate %}
             <button type="submit" name="_edit" formaction="{% url 'ipam:aggregate_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'ipam:aggregate_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/ipam/inc/ipaddress_table.html

@@ -2,6 +2,7 @@
 {% if perms.ipam.change_ipaddress or perms.ipam.delete_ipaddress %}
 {% if perms.ipam.change_ipaddress or perms.ipam.delete_ipaddress %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.ipam.change_ipaddress %}
         {% if perms.ipam.change_ipaddress %}
             <button type="submit" name="_edit" formaction="{% url 'ipam:ipaddress_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'ipam:ipaddress_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/ipam/inc/prefix_table.html

@@ -2,6 +2,7 @@
 {% if perms.ipam.change_prefix or perms.ipam.delete_prefix %}
 {% if perms.ipam.change_prefix or perms.ipam.delete_prefix %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.ipam.change_prefix %}
         {% if perms.ipam.change_prefix %}
             <button type="submit" name="_edit" formaction="{% url 'ipam:prefix_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'ipam:prefix_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/ipam/inc/vlan_table.html

@@ -2,6 +2,7 @@
 {% if perms.ipam.change_vlan or perms.ipam.delete_vlan %}
 {% if perms.ipam.change_vlan or perms.ipam.delete_vlan %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.ipam.change_vlan %}
         {% if perms.ipam.change_vlan %}
             <button type="submit" name="_edit" formaction="{% url 'ipam:vlan_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'ipam:vlan_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/ipam/inc/vrf_table.html

@@ -2,6 +2,7 @@
 {% if perms.ipam.change_vrf or perms.ipam.delete_vrf %}
 {% if perms.ipam.change_vrf or perms.ipam.delete_vrf %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.ipam.change_vrf %}
         {% if perms.ipam.change_vrf %}
             <button type="submit" name="_edit" formaction="{% url 'ipam:vrf_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'ipam:vrf_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 1 - 0
netbox/templates/secrets/inc/secret_table.html

@@ -2,6 +2,7 @@
 {% if perms.secrets.change_secret or perms.secrets.delete_secret %}
 {% if perms.secrets.change_secret or perms.secrets.delete_secret %}
     <form method="post" class="form form-horizontal">
     <form method="post" class="form form-horizontal">
         {% csrf_token %}
         {% csrf_token %}
+        <input type="hidden" name="redirect_url" value="{{ request.path }}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" />
         {% render_table table table_template|default:'table.html' %}
         {% render_table table table_template|default:'table.html' %}
         {% if perms.secret.change_secret %}
         {% if perms.secret.change_secret %}
             <button type="submit" name="_edit" formaction="{% url 'secrets:secret_bulk_edit' %}" class="btn btn-warning btn-sm">
             <button type="submit" name="_edit" formaction="{% url 'secrets:secret_bulk_edit' %}" class="btn btn-warning btn-sm">

+ 3 - 0
netbox/templates/utilities/bulk_edit_form.html

@@ -5,6 +5,9 @@
 <h1>{% block title %}{% endblock %}</h1>
 <h1>{% block title %}{% endblock %}</h1>
 <form action="." method="post" class="form form-horizontal">
 <form action="." method="post" class="form form-horizontal">
     {% csrf_token %}
     {% csrf_token %}
+    {% if request.POST.redirect_url %}
+        <input type="hidden" name="redirect_url" value="{{ request.POST.redirect_url }}" />
+    {% endif %}
     {% for hidden in form.hidden_fields %}
     {% for hidden in form.hidden_fields %}
         {{ hidden }}
         {{ hidden }}
     {% endfor %}
     {% endfor %}

+ 25 - 11
netbox/utilities/views.py

@@ -9,6 +9,7 @@ from django.http import HttpResponseRedirect
 from django.shortcuts import get_object_or_404, redirect, render
 from django.shortcuts import get_object_or_404, redirect, render
 from django.template import TemplateSyntaxError
 from django.template import TemplateSyntaxError
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
+from django.utils.http import is_safe_url
 from django.views.generic import View
 from django.views.generic import View
 
 
 from django_tables2 import RequestConfig
 from django_tables2 import RequestConfig
@@ -122,20 +123,26 @@ class BulkEditView(View):
     cls = None
     cls = None
     form = None
     form = None
     template_name = None
     template_name = None
-    redirect_url = None
+    default_redirect_url = None
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
-        return redirect(self.redirect_url)
+        return redirect(self.default_redirect_url)
 
 
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
 
 
+        posted_redirect_url = request.POST.get('redirect_url')
+        if posted_redirect_url and is_safe_url(url=posted_redirect_url, host=request.get_host()):
+            redirect_url = posted_redirect_url
+        else:
+            redirect_url = reverse(self.default_redirect_url)
+
         if '_apply' in request.POST:
         if '_apply' in request.POST:
             form = self.form(request.POST)
             form = self.form(request.POST)
             if form.is_valid():
             if form.is_valid():
                 pk_list = [obj.pk for obj in form.cleaned_data['pk']]
                 pk_list = [obj.pk for obj in form.cleaned_data['pk']]
                 self.update_objects(pk_list, form)
                 self.update_objects(pk_list, form)
                 if not form.errors:
                 if not form.errors:
-                    return redirect(self.redirect_url)
+                    return redirect(redirect_url)
 
 
         else:
         else:
             form = self.form(initial={'pk': request.POST.getlist('pk')})
             form = self.form(initial={'pk': request.POST.getlist('pk')})
@@ -143,12 +150,12 @@ class BulkEditView(View):
         selected_objects = self.cls.objects.filter(pk__in=request.POST.getlist('pk'))
         selected_objects = self.cls.objects.filter(pk__in=request.POST.getlist('pk'))
         if not selected_objects:
         if not selected_objects:
             messages.warning(request, "No {} were selected.".format(self.cls._meta.verbose_name_plural))
             messages.warning(request, "No {} were selected.".format(self.cls._meta.verbose_name_plural))
-            return redirect(self.redirect_url)
+            return redirect(redirect_url)
 
 
         return render(request, self.template_name, {
         return render(request, self.template_name, {
             'form': form,
             'form': form,
             'selected_objects': selected_objects,
             'selected_objects': selected_objects,
-            'cancel_url': reverse(self.redirect_url),
+            'cancel_url': redirect_url,
         })
         })
 
 
     def update_objects(self, obj_list, form):
     def update_objects(self, obj_list, form):
@@ -162,16 +169,23 @@ class BulkDeleteView(View):
     cls = None
     cls = None
     form = None
     form = None
     template_name = None
     template_name = None
-    redirect_url = None
+    default_redirect_url = None
 
 
     @method_decorator(staff_member_required)
     @method_decorator(staff_member_required)
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(BulkDeleteView, self).dispatch(*args, **kwargs)
         return super(BulkDeleteView, self).dispatch(*args, **kwargs)
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
-        return redirect(self.redirect_url)
+        return redirect(self.default_redirect_url)
 
 
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
+
+        posted_redirect_url = request.POST.get('redirect_url')
+        if posted_redirect_url and is_safe_url(url=posted_redirect_url, host=request.get_host()):
+            redirect_url = posted_redirect_url
+        else:
+            redirect_url = reverse(self.default_redirect_url)
+
         if '_confirm' in request.POST:
         if '_confirm' in request.POST:
             form = self.form(request.POST)
             form = self.form(request.POST)
             if form.is_valid():
             if form.is_valid():
@@ -183,10 +197,10 @@ class BulkDeleteView(View):
                     objects_to_delete.delete()
                     objects_to_delete.delete()
                 except ProtectedError, e:
                 except ProtectedError, e:
                     handle_protectederror(list(objects_to_delete), request, e)
                     handle_protectederror(list(objects_to_delete), request, e)
-                    return redirect(self.redirect_url)
+                    return redirect(redirect_url)
 
 
                 messages.success(request, "Deleted {} {}".format(deleted_count, self.cls._meta.verbose_name_plural))
                 messages.success(request, "Deleted {} {}".format(deleted_count, self.cls._meta.verbose_name_plural))
-                return redirect(self.redirect_url)
+                return redirect(redirect_url)
 
 
         else:
         else:
             form = self.form(initial={'pk': request.POST.getlist('pk')})
             form = self.form(initial={'pk': request.POST.getlist('pk')})
@@ -194,10 +208,10 @@ class BulkDeleteView(View):
         selected_objects = self.cls.objects.filter(pk__in=form.initial.get('pk'))
         selected_objects = self.cls.objects.filter(pk__in=form.initial.get('pk'))
         if not selected_objects:
         if not selected_objects:
             messages.warning(request, "No {} were selected for deletion.".format(self.cls._meta.verbose_name_plural))
             messages.warning(request, "No {} were selected for deletion.".format(self.cls._meta.verbose_name_plural))
-            return redirect(self.redirect_url)
+            return redirect(redirect_url)
 
 
         return render(request, self.template_name, {
         return render(request, self.template_name, {
             'form': form,
             'form': form,
             'selected_objects': selected_objects,
             'selected_objects': selected_objects,
-            'cancel_url': reverse(self.redirect_url),
+            'cancel_url': redirect_url,
         })
         })