Процесс обработки и UniqueConstraint Django
Я сделал модель с ограничениями:
class DiscountSchema(models.Model):
...
class Meta:
verbose_name = "DiscountSchema"
constraints = [
constraints.UniqueConstraint(
fields=(
"level",
"level_value",
"discount_rate",
"background_col",
"foreground_col",
"loyalty_card",
),
violation_error_message="UNIQUEERROR",
name="Uniqueschema",
)
]
Как я могу обработать эти ограничения при создании экземпляра в сериализаторе? Сейчас у меня есть:
try:
serializer.is_valid(raise_exception=True)
return serializer.save()
except IntegrityError as e:
if "Uniqueschema" in e.args[0]:
pass
else:
raise e
Есть ли лучший способ?
Предполагая, что вы используете CreateView
какого-то типа (ListCreateView
, или ModelViewSet
и т.д.), вы могли бы переопределить метод create
, который мог бы быть немного чище?
class DiscountSchema(ListCreateView):
...
def create(self, request, *args, **kwargs):
try:
return super().create(request, *args, **kwargs)
except IntegrityError:
return Response(status=400)
Если у вас есть уникальные ограничения на ряд моделей, вы можете реализовать пользовательский обработчик исключений для DRF, чтобы не вводить эту логику в каждое представление.
Вы регистрируете свой обработчик в DRF в настройках:
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'api.handlers.custom_exception_handler'}
(замените значение на то, куда вы поместили свой обработчик)
Затем определите что-то вроде этого для вашего обработчика:
from __future__ import unicode_literals
from django.db import IntegrityError
from rest_framework.views import Response, exception_handler
from rest_framework import status
def custom_exception_handler(exc, context):
response = exception_handler(exc, context)
if isinstance(exc, IntegrityError) and not response:
response = Response(
{'message': '<your error message here>'},
status=status.HTTP_400_BAD_REQUEST,
)
return response
Помните, что если вы решите использовать свой собственный обработчик исключений, то при вызове serializer.is_valid()
вручную в любом месте вашего кода (например, если вы переопределили какие-либо наборы представлений DRF и вызвали serializer.is_valid()
), вам нужно будет добавить raises_exception
к вызову is_valid()
следующим образом
serializer.is_valid(raise_exception=True)
. Чтобы запустить ваш обработчик исключений, ему необходимо поднять исключение.
Надеюсь, это поможет!