Django-rest-framework: DestroyAPIView error when on_delete=models.PROTECT

Created on 25 Apr 2018  ·  4Comments  ·  Source: encode/django-rest-framework

Steps to reproduce

models:

class Region(models.Model):
    name = models.CharField(max_length=255)
    code = models.IntegerField()


class District(models.Model):
    region = models.ForeignKey('Region', related_name='districts', on_delete=models.PROTECT)
    name = models.CharField(max_length=255)
    code = models.IntegerField()

views:

class RegionDelete(generics.DestroyAPIView):
    queryset = Region.objects.all()
    serializer_class = RegionSerializer

Expected behavior

HTTP code 423 or other.
Error detail.

Actual behavior

Django exception

Fix for me

mixins:

class DestroyModelMixin(object):
    """
    Destroy a model instance.
    """
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        try:
            self.perform_destroy(instance)
        except django.db.models.deletion.ProtectedError as e:
            return Response(status=status.HTTP_423_LOCKED, data={'detail':str(e)})
        return Response(status=status.HTTP_204_NO_CONTENT)

    def perform_destroy(self, instance):
        instance.delete()

Most helpful comment

This can be fixed with just a couple of lines of code. Frameworks are supposed to make life easier so I think automatic exception handling for model delete should be added.

All 4 comments

You’ll need to write a custom method to handle this case. I don’t think it’s common enough to warrant adding the extra complexity to the standard case.

This can be fixed with just a couple of lines of code. Frameworks are supposed to make life easier so I think automatic exception handling for model delete should be added.

Old issue, but still oh so relevant.

From my point of view it's very common and serves as a crucial part to keep your database integrity.

Running into this as well. Would be very nice to have this handled by default without a 500 error.

Was this page helpful?
0 / 5 - 0 ratings