我的应用程序中有一个用户模型,在电子邮件上有一个唯一的字段。然而,我需要了解用户何时试图进行重复请求,这样我就可以用不同的方式进行一些处理。
我正在进行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
参考
- 异常
- 唯一约束错误代码