Merge "Improve exception message in network related Batch/DeleteAction"
This commit is contained in:
@@ -17,7 +17,6 @@ import logging
|
|||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.core.urlresolvers import reverse_lazy
|
from django.core.urlresolvers import reverse_lazy
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.translation import ungettext_lazy
|
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
@@ -33,38 +32,6 @@ from openstack_dashboard.usage import quotas
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DeleteSubnet(proj_tables.SubnetPolicyTargetMixin, tables.DeleteAction):
|
|
||||||
@staticmethod
|
|
||||||
def action_present(count):
|
|
||||||
return ungettext_lazy(
|
|
||||||
u"Delete Subnet",
|
|
||||||
u"Delete Subnets",
|
|
||||||
count
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def action_past(count):
|
|
||||||
return ungettext_lazy(
|
|
||||||
u"Deleted Subnet",
|
|
||||||
u"Deleted Subnets",
|
|
||||||
count
|
|
||||||
)
|
|
||||||
|
|
||||||
policy_rules = (("network", "delete_subnet"),)
|
|
||||||
|
|
||||||
def delete(self, request, obj_id):
|
|
||||||
try:
|
|
||||||
api.neutron.subnet_delete(request, obj_id)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.info('Failed to delete subnet %(id)s: %(exc)s',
|
|
||||||
{'id': obj_id, 'exc': e})
|
|
||||||
msg = _('Failed to delete subnet %s') % obj_id
|
|
||||||
network_id = self.table.kwargs['network_id']
|
|
||||||
redirect = reverse('horizon:admin:networks:detail',
|
|
||||||
args=[network_id])
|
|
||||||
exceptions.handle(request, msg, redirect=redirect)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSubnet(proj_tables.SubnetPolicyTargetMixin, tables.LinkAction):
|
class CreateSubnet(proj_tables.SubnetPolicyTargetMixin, tables.LinkAction):
|
||||||
name = "create"
|
name = "create"
|
||||||
verbose_name = _("Create Subnet")
|
verbose_name = _("Create Subnet")
|
||||||
@@ -149,8 +116,9 @@ class SubnetsTable(tables.DataTable):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
name = "subnets"
|
name = "subnets"
|
||||||
verbose_name = _("Subnets")
|
verbose_name = _("Subnets")
|
||||||
table_actions = (CreateSubnet, DeleteSubnet, tables.FilterAction,)
|
table_actions = (CreateSubnet, proj_tables.DeleteSubnet,
|
||||||
row_actions = (UpdateSubnet, DeleteSubnet,)
|
tables.FilterAction,)
|
||||||
|
row_actions = (UpdateSubnet, proj_tables.DeleteSubnet,)
|
||||||
hidden_title = False
|
hidden_title = False
|
||||||
|
|
||||||
def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):
|
def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):
|
||||||
|
@@ -14,11 +14,9 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
from django.template import defaultfilters as filters
|
from django.template import defaultfilters as filters
|
||||||
from django.utils.translation import pgettext_lazy
|
from django.utils.translation import pgettext_lazy
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.translation import ungettext_lazy
|
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
@@ -32,36 +30,6 @@ from openstack_dashboard.usage import quotas
|
|||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DeleteNetwork(policy.PolicyTargetMixin, tables.DeleteAction):
|
|
||||||
@staticmethod
|
|
||||||
def action_present(count):
|
|
||||||
return ungettext_lazy(
|
|
||||||
u"Delete Network",
|
|
||||||
u"Delete Networks",
|
|
||||||
count
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def action_past(count):
|
|
||||||
return ungettext_lazy(
|
|
||||||
u"Deleted Network",
|
|
||||||
u"Deleted Networks",
|
|
||||||
count
|
|
||||||
)
|
|
||||||
|
|
||||||
policy_rules = (("network", "delete_network"),)
|
|
||||||
|
|
||||||
def delete(self, request, obj_id):
|
|
||||||
try:
|
|
||||||
api.neutron.network_delete(request, obj_id)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.info('Failed to delete network %(id)s: %(exc)s',
|
|
||||||
{'id': obj_id, 'exc': e})
|
|
||||||
msg = _('Failed to delete network %s') % obj_id
|
|
||||||
redirect = reverse('horizon:admin:networks:index')
|
|
||||||
exceptions.handle(request, msg, redirect=redirect)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateNetwork(tables.LinkAction):
|
class CreateNetwork(tables.LinkAction):
|
||||||
name = "create"
|
name = "create"
|
||||||
verbose_name = _("Create Network")
|
verbose_name = _("Create Network")
|
||||||
@@ -147,9 +115,9 @@ class NetworksTable(tables.DataTable):
|
|||||||
class Meta(object):
|
class Meta(object):
|
||||||
name = "networks"
|
name = "networks"
|
||||||
verbose_name = _("Networks")
|
verbose_name = _("Networks")
|
||||||
table_actions = (CreateNetwork, DeleteNetwork,
|
table_actions = (CreateNetwork, project_tables.DeleteNetwork,
|
||||||
AdminNetworksFilterAction)
|
AdminNetworksFilterAction)
|
||||||
row_actions = (EditNetwork, CreateSubnet, DeleteNetwork)
|
row_actions = (EditNetwork, CreateSubnet, project_tables.DeleteNetwork)
|
||||||
|
|
||||||
def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):
|
def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):
|
||||||
super(NetworksTable, self).__init__(
|
super(NetworksTable, self).__init__(
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from neutronclient.common import exceptions as neutron_exceptions
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.core.urlresolvers import reverse_lazy
|
from django.core.urlresolvers import reverse_lazy
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
@@ -21,6 +23,7 @@ from django.utils.translation import ungettext_lazy
|
|||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
|
from horizon.tables import actions
|
||||||
from horizon.utils import memoized
|
from horizon.utils import memoized
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
@@ -73,17 +76,20 @@ class DeleteSubnet(SubnetPolicyTargetMixin, tables.DeleteAction):
|
|||||||
|
|
||||||
policy_rules = (("network", "delete_subnet"),)
|
policy_rules = (("network", "delete_subnet"),)
|
||||||
|
|
||||||
|
@actions.handle_exception_with_detail_message(
|
||||||
|
# normal_log_message
|
||||||
|
'Failed to delete subnet %(id)s: %(exc)s',
|
||||||
|
# target_exception
|
||||||
|
neutron_exceptions.Conflict,
|
||||||
|
# target_log_message
|
||||||
|
'Unable to delete subnet %(id)s with 409 Conflict: %(exc)s',
|
||||||
|
# target_user_message
|
||||||
|
_('Unable to delete subnet %(name)s. Most possible reason is because '
|
||||||
|
'one or more ports have an IP allocation from this subnet.'),
|
||||||
|
# logger_name
|
||||||
|
__name__)
|
||||||
def delete(self, request, obj_id):
|
def delete(self, request, obj_id):
|
||||||
try:
|
api.neutron.subnet_delete(request, obj_id)
|
||||||
api.neutron.subnet_delete(request, obj_id)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.info('Failed to delete subnet %(id)s: %(exc)s',
|
|
||||||
{'id': obj_id, 'exc': e})
|
|
||||||
msg = _('Failed to delete subnet %s') % obj_id
|
|
||||||
network_id = self.table.kwargs['network_id']
|
|
||||||
redirect = reverse('horizon:project:networks:detail',
|
|
||||||
args=[network_id])
|
|
||||||
exceptions.handle(request, msg, redirect=redirect)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateSubnet(SubnetPolicyTargetMixin, tables.LinkAction):
|
class CreateSubnet(SubnetPolicyTargetMixin, tables.LinkAction):
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse_lazy
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.template import defaultfilters as filters
|
from django.template import defaultfilters as filters
|
||||||
from django.utils.translation import pgettext_lazy
|
from django.utils.translation import pgettext_lazy
|
||||||
@@ -23,6 +22,7 @@ from neutronclient.common import exceptions as neutron_exceptions
|
|||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
|
from horizon.tables import actions
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.dashboards.project.networks.subnets import tables \
|
from openstack_dashboard.dashboards.project.networks.subnets import tables \
|
||||||
@@ -53,34 +53,24 @@ class DeleteNetwork(policy.PolicyTargetMixin, tables.DeleteAction):
|
|||||||
|
|
||||||
policy_rules = (("network", "delete_network"),)
|
policy_rules = (("network", "delete_network"),)
|
||||||
|
|
||||||
|
@actions.handle_exception_with_detail_message(
|
||||||
|
# normal_log_message
|
||||||
|
'Failed to delete network %(id)s: %(exc)s',
|
||||||
|
# target_exception
|
||||||
|
neutron_exceptions.Conflict,
|
||||||
|
# target_log_message
|
||||||
|
'Unable to delete network %(id)s with 409 Conflict: %(exc)s',
|
||||||
|
# target_user_message
|
||||||
|
_('Unable to delete network %(name)s. Most possible reason is because '
|
||||||
|
'one or more ports still exist on the requested network.'),
|
||||||
|
# logger_name
|
||||||
|
__name__)
|
||||||
def delete(self, request, network_id):
|
def delete(self, request, network_id):
|
||||||
network_name = network_id
|
network = self.table.get_object_by_id(network_id)
|
||||||
redirect_url = reverse_lazy("horizon:project:networks:index")
|
LOG.debug('Network %(network_id)s has subnets: %(subnets)s',
|
||||||
try:
|
{'network_id': network_id, 'subnets': network.subnets})
|
||||||
# Retrieve the network list.
|
api.neutron.network_delete(request, network_id)
|
||||||
network = api.neutron.network_get(request, network_id,
|
LOG.debug('Deleted network %s successfully', network_id)
|
||||||
expand_subnet=False)
|
|
||||||
network_name = network.name
|
|
||||||
LOG.debug('Network %(network_id)s has subnets: %(subnets)s',
|
|
||||||
{'network_id': network_id, 'subnets': network.subnets})
|
|
||||||
for subnet_id in network.subnets:
|
|
||||||
api.neutron.subnet_delete(request, subnet_id)
|
|
||||||
LOG.debug('Deleted subnet %s', subnet_id)
|
|
||||||
api.neutron.network_delete(request, network_id)
|
|
||||||
LOG.debug('Deleted network %s successfully', network_id)
|
|
||||||
except neutron_exceptions.Conflict as e:
|
|
||||||
LOG.info('Failed to delete network %(id)s with 409 Conflict: '
|
|
||||||
'%(exc)s', {'id': network_id, 'exc': e})
|
|
||||||
msg = (_('Failed to delete network %(network_name)s. '
|
|
||||||
'Most possible case is that one or more ports still '
|
|
||||||
'exist on the requested network.') %
|
|
||||||
{"network_name": network_name, "subnet_id": subnet_id})
|
|
||||||
exceptions.handle(request, msg, redirect=redirect_url)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.info('Failed to delete network %(id)s: %(exc)s',
|
|
||||||
{'id': network_id, 'exc': e})
|
|
||||||
msg = _('Failed to delete network %s') % network_name
|
|
||||||
exceptions.handle(request, msg, redirect=redirect_url)
|
|
||||||
|
|
||||||
|
|
||||||
class CreateNetwork(tables.LinkAction):
|
class CreateNetwork(tables.LinkAction):
|
||||||
|
@@ -1011,10 +1011,6 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
|
|||||||
def test_delete_network_no_subnet(self):
|
def test_delete_network_no_subnet(self):
|
||||||
network = self.networks.first()
|
network = self.networks.first()
|
||||||
network.subnets = []
|
network.subnets = []
|
||||||
api.neutron.network_get(IsA(http.HttpRequest),
|
|
||||||
network.id,
|
|
||||||
expand_subnet=False)\
|
|
||||||
.AndReturn(network)
|
|
||||||
api.neutron.is_extension_supported(
|
api.neutron.is_extension_supported(
|
||||||
IsA(http.HttpRequest), 'network_availability_zone')\
|
IsA(http.HttpRequest), 'network_availability_zone')\
|
||||||
.MultipleTimes().AndReturn(True)
|
.MultipleTimes().AndReturn(True)
|
||||||
@@ -1030,23 +1026,13 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
|
|||||||
@test.create_stubs({api.neutron: ('network_get',
|
@test.create_stubs({api.neutron: ('network_get',
|
||||||
'network_list',
|
'network_list',
|
||||||
'network_delete',
|
'network_delete',
|
||||||
'subnet_delete',
|
|
||||||
'is_extension_supported')})
|
'is_extension_supported')})
|
||||||
def test_delete_network_with_subnet(self):
|
def test_delete_network_with_subnet(self):
|
||||||
network = self.networks.first()
|
network = self.networks.first()
|
||||||
network.subnets = [subnet.id for subnet in network.subnets]
|
|
||||||
subnet_id = network.subnets[0]
|
|
||||||
subnetv6_id = network.subnets[1]
|
|
||||||
api.neutron.network_get(IsA(http.HttpRequest),
|
|
||||||
network.id,
|
|
||||||
expand_subnet=False)\
|
|
||||||
.AndReturn(network)
|
|
||||||
api.neutron.is_extension_supported(
|
api.neutron.is_extension_supported(
|
||||||
IsA(http.HttpRequest), 'network_availability_zone')\
|
IsA(http.HttpRequest), 'network_availability_zone')\
|
||||||
.MultipleTimes().AndReturn(True)
|
.MultipleTimes().AndReturn(True)
|
||||||
self._stub_net_list()
|
self._stub_net_list()
|
||||||
api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
|
|
||||||
api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
|
|
||||||
api.neutron.network_delete(IsA(http.HttpRequest), network.id)
|
api.neutron.network_delete(IsA(http.HttpRequest), network.id)
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@@ -1059,23 +1045,13 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
|
|||||||
@test.create_stubs({api.neutron: ('network_get',
|
@test.create_stubs({api.neutron: ('network_get',
|
||||||
'network_list',
|
'network_list',
|
||||||
'network_delete',
|
'network_delete',
|
||||||
'subnet_delete',
|
|
||||||
'is_extension_supported')})
|
'is_extension_supported')})
|
||||||
def test_delete_network_exception(self):
|
def test_delete_network_exception(self):
|
||||||
network = self.networks.first()
|
network = self.networks.first()
|
||||||
network.subnets = [subnet.id for subnet in network.subnets]
|
|
||||||
subnet_id = network.subnets[0]
|
|
||||||
subnetv6_id = network.subnets[1]
|
|
||||||
api.neutron.network_get(IsA(http.HttpRequest),
|
|
||||||
network.id,
|
|
||||||
expand_subnet=False)\
|
|
||||||
.AndReturn(network)
|
|
||||||
api.neutron.is_extension_supported(
|
api.neutron.is_extension_supported(
|
||||||
IsA(http.HttpRequest), 'network_availability_zone')\
|
IsA(http.HttpRequest), 'network_availability_zone')\
|
||||||
.MultipleTimes().AndReturn(True)
|
.MultipleTimes().AndReturn(True)
|
||||||
self._stub_net_list()
|
self._stub_net_list()
|
||||||
api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
|
|
||||||
api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
|
|
||||||
api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
|
api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
|
||||||
.AndRaise(self.exceptions.neutron)
|
.AndRaise(self.exceptions.neutron)
|
||||||
|
|
||||||
|
@@ -19,11 +19,11 @@ from django.template import defaultfilters as filters
|
|||||||
from django.utils.translation import pgettext_lazy
|
from django.utils.translation import pgettext_lazy
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.translation import ungettext_lazy
|
from django.utils.translation import ungettext_lazy
|
||||||
from neutronclient.common import exceptions as q_ext
|
from neutronclient.common import exceptions as neutron_exceptions
|
||||||
|
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
from horizon import messages
|
|
||||||
from horizon import tables
|
from horizon import tables
|
||||||
|
from horizon.tables import actions
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard import policy
|
from openstack_dashboard import policy
|
||||||
@@ -53,38 +53,26 @@ class DeleteRouter(policy.PolicyTargetMixin, tables.DeleteAction):
|
|||||||
redirect_url = "horizon:project:routers:index"
|
redirect_url = "horizon:project:routers:index"
|
||||||
policy_rules = (("network", "delete_router"),)
|
policy_rules = (("network", "delete_router"),)
|
||||||
|
|
||||||
|
@actions.handle_exception_with_detail_message(
|
||||||
|
# normal_log_message
|
||||||
|
'Failed to delete router %(id)s: %(exc)s',
|
||||||
|
# target_exception
|
||||||
|
neutron_exceptions.NeutronClientException,
|
||||||
|
# target_log_message
|
||||||
|
'Unable to delete router %(id)s: %(exc)s',
|
||||||
|
# target_user_message
|
||||||
|
_('Unable to delete router %(name)s: %(exc)s'),
|
||||||
|
# logger_name
|
||||||
|
__name__)
|
||||||
def delete(self, request, obj_id):
|
def delete(self, request, obj_id):
|
||||||
try:
|
# detach all interfaces before attempting to delete the router
|
||||||
# detach all interfaces before attempting to delete the router
|
search_opts = {'device_owner': 'network:router_interface',
|
||||||
search_opts = {'device_owner': 'network:router_interface',
|
'device_id': obj_id}
|
||||||
'device_id': obj_id}
|
ports = api.neutron.port_list(request, **search_opts)
|
||||||
ports = api.neutron.port_list(request, **search_opts)
|
for port in ports:
|
||||||
for port in ports:
|
api.neutron.router_remove_interface(request, obj_id,
|
||||||
api.neutron.router_remove_interface(request, obj_id,
|
port_id=port.id)
|
||||||
port_id=port.id)
|
api.neutron.router_delete(request, obj_id)
|
||||||
api.neutron.router_delete(request, obj_id)
|
|
||||||
except q_ext.NeutronClientException as e:
|
|
||||||
# TODO(amotoki): Revisit why Http302 needs to be raised.
|
|
||||||
# We have this pattern ONLY HERE.
|
|
||||||
# Can't we merge two except clauses?
|
|
||||||
LOG.info('Unable to delete router %(id)s: %(exc)s',
|
|
||||||
{'id': obj_id, 'exc': e})
|
|
||||||
obj = self.table.get_object_by_id(obj_id)
|
|
||||||
name = self.table.get_object_display(obj)
|
|
||||||
msg = _('Unable to delete router "%s"') % name
|
|
||||||
messages.error(request, msg)
|
|
||||||
redirect = reverse(self.redirect_url)
|
|
||||||
raise exceptions.Http302(redirect, message=msg)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.info('Unable to delete router %(id)s: %(exc)s',
|
|
||||||
{'id': obj_id, 'exc': e})
|
|
||||||
obj = self.table.get_object_by_id(obj_id)
|
|
||||||
name = self.table.get_object_display(obj)
|
|
||||||
msg = _('Unable to delete router "%s"') % name
|
|
||||||
exceptions.handle(request, msg)
|
|
||||||
|
|
||||||
def allowed(self, request, router=None):
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class CreateRouter(tables.LinkAction):
|
class CreateRouter(tables.LinkAction):
|
||||||
@@ -159,19 +147,21 @@ class ClearGateway(policy.PolicyTargetMixin, tables.BatchAction):
|
|||||||
policy_rules = (("network", "update_router"),)
|
policy_rules = (("network", "update_router"),)
|
||||||
action_type = "danger"
|
action_type = "danger"
|
||||||
|
|
||||||
|
@actions.handle_exception_with_detail_message(
|
||||||
|
# normal_log_message
|
||||||
|
'Unable to clear gateway for router %(id)s: %(exc)s',
|
||||||
|
# target_exception
|
||||||
|
neutron_exceptions.Conflict,
|
||||||
|
# target_log_message
|
||||||
|
'Unable to clear gateway for router %(id)s: %(exc)s',
|
||||||
|
# target_user_message
|
||||||
|
_('Unable to clear gateway for router %(name)s. '
|
||||||
|
'Most possible reason is because the gateway is required '
|
||||||
|
'by one or more floating IPs'),
|
||||||
|
# logger_name
|
||||||
|
__name__)
|
||||||
def action(self, request, obj_id):
|
def action(self, request, obj_id):
|
||||||
obj = self.table.get_object_by_id(obj_id)
|
api.neutron.router_remove_gateway(request, obj_id)
|
||||||
name = self.table.get_object_display(obj)
|
|
||||||
try:
|
|
||||||
api.neutron.router_remove_gateway(request, obj_id)
|
|
||||||
except Exception as e:
|
|
||||||
LOG.info('Unable to clear gateway for router %(id)s: %(exc)s',
|
|
||||||
{'id': obj_id, 'exc': e})
|
|
||||||
msg = (_('Unable to clear gateway for router '
|
|
||||||
'"%(name)s": "%(msg)s"')
|
|
||||||
% {"name": name, "msg": e})
|
|
||||||
redirect = reverse(self.redirect_url)
|
|
||||||
exceptions.handle(request, msg, redirect=redirect)
|
|
||||||
|
|
||||||
def get_success_url(self, request):
|
def get_success_url(self, request):
|
||||||
return reverse(self.redirect_url)
|
return reverse(self.redirect_url)
|
||||||
|
Reference in New Issue
Block a user