Django Rest Framework在我为ModelViewSet处理异常之前抛出了400



我的应用程序中有一个用户模型,在电子邮件上有一个唯一的字段。然而,我需要了解用户何时试图进行重复请求,这样我就可以用不同的方式进行一些处理。

我正在进行POST调用以创建此用户。DRF当然会用现有的电子邮件信息抛出一个400。

但是,即使我在模型中创建了validate_email方法,或者试图用自定义异常捕获它,它也无法捕获。

我创建了一个自定义ValidationError,因为除了通用代码unique或匹配消息字符串之外,通用ValidationError似乎没有办法专门过滤掉它。

如何在Django Rest Framework中捕获这种特定的验证

错误消息:

{
"email": [
"user with this email address already exists."
],
"status_code": 400
}

用户型号:

class User(AbstractBaseUser, PermissionsMixin):
"""
User Model
"""
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
email = models.EmailField(_("email address"), unique=True)
name = models.CharField(_("name"), max_length=30, blank=True)
def validate_email(self):
email = self.email
valid_email = email is not None and email.endswith(self.email_domain)
if not valid_email:
raise ValidationError(
_("Email is not valid"),
code="invalid.email",
)
if Users.objects.filter(email=email).exists():
import ipdb; ipdb.sset_trace() #does not get called 
raise EmailExists()

UserViewSet代码:

class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
serializer_class = UserSerializer
permission_classes = (IsAuthenticated,)
def get_serializer_class(self):
if self.action == 'list':
return UserSerializer
else:
return UserDetailSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
try:
serializer.is_valid(raise_exception=True)
except EmailExists:
logger.debug('caught the existing email')
import ipdb; ipdb.sset_trace()
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

自定义异常:

from rest_framework.exceptions import ValidationError
class EmailExists(ValidationError):
"""Raised when user exists"""
pass

您需要捕获一个ValidationError异常。这背后的原因是因为你已经定义了你的电子邮件字段unique=True,当你调用serializer.is_valid()时,Django会自动检查。

此外,您可以使用exc. get_full_details()检查唯一约束错误

try:
serializer.is_valid(raise_exception=True)
except ValidationError as exc:
errors = exc.get_full_details()
if 'email' in errors and errors['email']['code'] == 'unique':
# do something, maybe re-raise with your custom exception:
raise EmailExists from exc

参考

  • 异常
  • 唯一约束错误代码

相关内容

  • 没有找到相关文章

最新更新