Django的处理流程和UniqueConstraint

问题描述 投票:0回答:1

我做了有约束的模型:

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

还有更好的办法吗?

python django postgresql django-rest-framework orm
1个回答
0
投票

假设您正在使用某种

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)
。至于要运行的自定义异常处理程序,它需要引发异常。

希望这有帮助!

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.