我做了有约束的模型:
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)
。至于要运行的自定义异常处理程序,它需要引发异常。
希望这有帮助!