Merge pull request #3222 from hellerve/tmp

Fix error message on trying to delete protected models
This commit is contained in:
Jeremy Stretch 2019-05-29 10:24:28 -04:00 committed by GitHub
commit a7ca49c44d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 2 deletions

View File

@ -1,3 +1,5 @@
import json
from django.urls import reverse from django.urls import reverse
from netaddr import IPNetwork from netaddr import IPNetwork
from rest_framework import status from rest_framework import status
@ -870,6 +872,8 @@ class VLANTest(APITestCase):
self.vlan2 = VLAN.objects.create(vid=2, name='Test VLAN 2') self.vlan2 = VLAN.objects.create(vid=2, name='Test VLAN 2')
self.vlan3 = VLAN.objects.create(vid=3, name='Test VLAN 3') self.vlan3 = VLAN.objects.create(vid=3, name='Test VLAN 3')
self.prefix1 = Prefix.objects.create(prefix=IPNetwork('192.168.1.0/24'))
def test_get_vlan(self): def test_get_vlan(self):
url = reverse('ipam-api:vlan-detail', kwargs={'pk': self.vlan1.pk}) url = reverse('ipam-api:vlan-detail', kwargs={'pk': self.vlan1.pk})
@ -960,6 +964,20 @@ class VLANTest(APITestCase):
self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT) self.assertHttpStatus(response, status.HTTP_204_NO_CONTENT)
self.assertEqual(VLAN.objects.count(), 2) self.assertEqual(VLAN.objects.count(), 2)
def test_delete_vlan_with_prefix(self):
self.prefix1.vlan = self.vlan1
self.prefix1.save()
url = reverse('ipam-api:vlan-detail', kwargs={'pk': self.vlan1.pk})
response = self.client.delete(url, **self.header)
# can't use assertHttpStatus here because we don't have response.data
self.assertEqual(response.status_code, 409)
content = json.loads(response.content.decode('utf-8'))
self.assertIn('detail', content)
self.assertTrue(content['detail'].startswith('You tried deleting a model that is protected by:'))
class ServiceTest(APITestCase): class ServiceTest(APITestCase):

View File

@ -4,7 +4,7 @@ import pytz
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist 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 django.http import Http404
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
from rest_framework.permissions import BasePermission from rest_framework.permissions import BasePermission
@ -248,6 +248,22 @@ class ModelViewSet(_ModelViewSet):
# Fall back to the hard-coded serializer class # Fall back to the hard-coded serializer class
return self.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): class FieldChoicesViewSet(ViewSet):
""" """

View File

@ -70,7 +70,6 @@ class ExceptionHandlingMiddleware(object):
custom_template = 'exceptions/import_error.html' custom_template = 'exceptions/import_error.html'
elif isinstance(exception, PermissionError): elif isinstance(exception, PermissionError):
custom_template = 'exceptions/permission_error.html' custom_template = 'exceptions/permission_error.html'
# Return a custom error message, or fall back to Django's default 500 error handling # Return a custom error message, or fall back to Django's default 500 error handling
if custom_template: if custom_template:
return server_error(request, template_name=custom_template) return server_error(request, template_name=custom_template)