Django rest framwork - как предотвратить 1062, "Дублирование записи"

В моем приложении Django (только DRF) я пытаюсь создать новый объект, где одно из полей настроено следующим образом:

 resource_name = models.CharField(verbose_name="Resource Name", blank=False, null=False, max_length=50, unique=True)
< < <

Как правило, вы должны разработать сериализатор для каждой модели, чтобы понять, как вы работаете с каждой из них. Позже вы можете забыть об этом "общем" решении и долго искать ошибку.

Тем не менее, я вижу два подхода для достижения такого поведения.

Оверриден ModelViewSet

Мы можем переопределить create метод default ModelViewSet и затем наследовать ваши ModelViewSet от этого класса. Например, так:

from django.db import IntegrityError
from rest_framework import viewsets
from rest_framework.exceptions import APIException
from rest_framework.status import HTTP_400_BAD_REQUEST

class SupressIntegrityErrorModelViewSet(viewsets.ModelViewSet):
    def create(self, request, *args, **kwargs):
        try:
            return super().create(request, *args, **kwargs)
        except IntegrityError as e:
            raise APIException(detail=str(e), code=HTTP_400_BAD_REQUEST)

Больше информации здесь.

DRF пользовательская обработка исключений

Сначала вам нужно сделать метод custom_exception_handler; документация DRF предлагает сделать его в <application-directory>/utils.py:

from django.http import HttpResponseBadRequest
from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
    if type(exc).__name__ == 'IntegrityError':
        return HttpResponseBadRequest(str(e))

    return exception_handler(exc, context)

Тогда вы должны установить EXCEPTION_HANDLER в вашем settings.py:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

Лучше добавить UniqueValidator в ваш сериализатор.

resource_name = serializers.CharField(max_length=50, validators=[UniqueValidator(queryset=YourModel.objects.all())], requierd=False) 
Вернуться на верх