Джанго 1,11

Я строю фотоархив. Через AJAX я добавляю некоторую информацию в фреймы (комментарии, заметки, места и т. Д.).

Но теперь я хочу организовать удаление кадра.

Похоже, это уместный вопрос, который мне удалось найти: Обработка ошибки защиты в Django DeleteView

Что мне нужно, так это сообщить пользователю: вы пытаетесь подстричь траву из-под ног других объектов.

Ответ Берислава Лопача по ссылке выше кажется разумным.

Теперь на производственном сервере я получаю следующее:

Ошибка сервера (500)

В режиме отладки я вижу ProtectedError.

Не могли бы вы помочь мне понять, как показать содержательное сообщение пользователю в процессе производства? Просто перехватите сообщение ProtectedError и покажите его вместо ошибки сервера (500).

< STRONG> моделей

class Frame(models.Model):

    type = models.CharField(max_length=10,
                            blank=False,
                            null=False,
                            default="---",
                            verbose_name=_('type'))


class FramePlace(CommonUrlMethodsMixin,
                models.Model
                ):

    frame = models.ForeignKey(Frame,
                              blank=False,
                              on_delete=models.PROTECT,
                              verbose_name=_("frame"))

    place = models.ForeignKey(Place,
                              blank=False,
                              on_delete=models.PROTECT,
                              verbose_name=_("place"))
2
Michael 28 Май 2017 в 19:49

2 ответа

Лучший ответ

Для этой проблемы. Я использую этот код ниже. Надеюсь, это поможет.

Здесь, чтобы поймать код ProtectedError ниже, работает.

from django.db.models import ProtectedError

def delete(self, request):
    obj = self.get_object()
    try:
        obj.delete()
        return JsonResponse( {"error":""} )

    except ProtectedError as e:
        return JsonResponse( {"error":"somae relation exists"} )

    except Exception as e:
        return JsonResponse( {"error":"something went wrong"} )

Надеюсь, это сработает для вас.

1
Chandan Sharma 12 Ноя 2019 в 11:48

Есть два способа добиться этого

  1. Переопределите методы perform_destroy или destroy требуемого ViewSet
  2. Добавьте промежуточное ПО для обработки исключений из всех ViewSets

1 - уровень ViewSet (определенный)

class MyViewSet(viewsets.ModelViewSet):
    def perform_destroy(self, instance):
        try:
            return super(MyViewSet, self).perform_destroy(instance)
        except ProtectedError as exception:
            data = {
                'code': 'server_error',
                'message': _('Internal server error.'),
                'error': {
                    'type': str(type(exception)),
                    'message': str(exception)
                }
            }
            return JsonResponse(data=data, status=status.HTTP_400_BAD_REQUEST)

2 - Уровень приложения (Общий)

< Сильный > middleware.py

class ExceptionMiddleware(object):
    """
    Middleware that makes sure clients see a meaningful error message wrapped in a Json response.
    """    
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_exception(self, request, exception):
        data = {
            'code': 'server_error',
            'message': _('Internal server error.'),
            'error': {
                'type': str(type(exception)),
                'message': str(exception)
            }
        }
        return JsonResponse(data=data, status=status.HTTP_400_BAD_REQUEST)

< Сильный > settings.py

MIDDLEWARE = [
    ...
    'myapp.middleware.ExceptionMiddleware'
]
5
Nour Wolf 28 Май 2017 в 19:28