From 2c7bad9fff4b4741f69c68586dbb624757221805 Mon Sep 17 00:00:00 2001 From: hellerve Date: Tue, 28 May 2019 21:11:23 +0200 Subject: [PATCH] utilities: move protectederror handling to modelviewset --- netbox/ipam/tests/test_api.py | 2 +- netbox/utilities/api.py | 18 +++++++++++++++++- netbox/utilities/middleware.py | 8 +------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/netbox/ipam/tests/test_api.py b/netbox/ipam/tests/test_api.py index 991f098bb..0dad73550 100644 --- a/netbox/ipam/tests/test_api.py +++ b/netbox/ipam/tests/test_api.py @@ -972,7 +972,7 @@ class VLANTest(APITestCase): response = self.client.delete(url, **self.header) # can't use assertHttpStatus here because we don't have response.data - self.assertEqual(response.status_code, 403) + self.assertEqual(response.status_code, 409) content = json.loads(response.content.decode('utf-8')) self.assertIn('detail', content) diff --git a/netbox/utilities/api.py b/netbox/utilities/api.py index fbebd09ff..9960fbe42 100644 --- a/netbox/utilities/api.py +++ b/netbox/utilities/api.py @@ -4,7 +4,7 @@ import pytz from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist -from django.db.models import ManyToManyField +from django.db.models import ManyToManyField, ProtectedError from django.http import Http404 from rest_framework.exceptions import APIException from rest_framework.permissions import BasePermission @@ -248,6 +248,22 @@ class ModelViewSet(_ModelViewSet): # Fall back to the hard-coded serializer class return self.serializer_class + def dispatch(self, request, *args, **kwargs): + try: + return super().dispatch(request, *args, **kwargs) + except ProtectedError as e: + models = '\n'.join( + '- {} ({})'.format(o, o._meta) + for o in e.protected_objects.all() + ) + msg = 'You tried deleting a model that is protected by:\n{}'.format(models) + return self.finalize_response( + request, + Response({'detail': msg}, status=409), + *args, + **kwargs + ) + class FieldChoicesViewSet(ViewSet): """ diff --git a/netbox/utilities/middleware.py b/netbox/utilities/middleware.py index 6be01127c..b2065543a 100644 --- a/netbox/utilities/middleware.py +++ b/netbox/utilities/middleware.py @@ -1,7 +1,6 @@ from django.conf import settings from django.db import ProgrammingError -from django.http import Http404, HttpResponseRedirect, JsonResponse -from django.db.models import ProtectedError +from django.http import Http404, HttpResponseRedirect from django.urls import reverse from .views import server_error @@ -63,11 +62,6 @@ class ExceptionHandlingMiddleware(object): if isinstance(exception, Http404): return - elif isinstance(exception, ProtectedError): - models = '\n'.join('- {} ({})'.format(o, o._meta) for o in exception.protected_objects.all()) - msg = 'You tried deleting a model that is protected by:\n{}'.format(models) - return JsonResponse({'detail': msg}, status=403) - # Determine the type of exception. If it's a common issue, return a custom error page with instructions. custom_template = None if isinstance(exception, ProgrammingError):