Просмотр исходного кода

utilities: move protectederror handling to modelviewset

hellerve 6 лет назад
Родитель
Сommit
2c7bad9fff
3 измененных файлов с 19 добавлено и 9 удалено
  1. 1 1
      netbox/ipam/tests/test_api.py
  2. 17 1
      netbox/utilities/api.py
  3. 1 7
      netbox/utilities/middleware.py

+ 1 - 1
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)

+ 17 - 1
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):
     """

+ 1 - 7
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):