AttributeError: объект 'str' не имеет атрибута 'ValidationError' Django
Я пытаюсь создать метод Views.py, в котором я проверяю, существует ли уже email в базе данных. Это работает для имени пользователя, но не работает для электронной почты или токенов. Как это можно сделать? Спасибо!
@api_view(['POST'])
def send_user_details(request):
if request.method == "POST":
serializer = SignUpDetailsForm(data=request.data)
if serializer.is_valid():
email = serializer.validated_data['email']
username = serializer.validated_data['username']
password = serializer.validated_data['password']
if User.objects.filter(email=email).exists():
raise email.ValidationError("Este Email ya está en uso")
if User.objects.filter(username=username).exists():
raise username.ValidationError("Este Usuario ya está en uso")
Выдает AttributeError: 'str' object has no attribute 'ValidationError'
Рассмотрите возможность переноса этих проверок в SignUpDetailForm
:
from django import forms
from django.core.exceptions import ValidationError
class SignUpDetailForm(forms.Form):
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError('Este Email ya está en uso')
def clean_username(self):
...
Источник: https://docs.djangoproject.com/en/3.2/ref/forms/validation/#cleaning-a-specific-field-attribute
Вы уверены, что это работает для username
?
AFAIK, мы должны поднимать ValidationError просто как объект исключения.
Мы не должны ожидать, что любое значение из формы вызовет это исключение.
from django.core.exceptions import ValidationError
if User.objects.filter(email=email).exists():
raise ValidationError("Este Email ya está en uso")
Вы не можете использовать raise
. email.ValidationError(…)email
- это str
инг, а у строки нет атрибута ValidationError
. Это также нелогично, поскольку переменная email не содержит слова email.
Ваше имя пользователя также не проверяется: это делает сериализатор, и сериализатор просто ошибается на этом, потому что поле username
модели User
требует, чтобы username
было уникальным. Поэтому сериализатор подтвердит это.
Вариант 1: проверка сериализатором
Вы можете реализовать логику и для электронного письма. Например, определив собственную модель или добавив UniqueValidator
[DRF-doc] к полю сериализации email:
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
class SignUpDetailsForm(serializers.ModelSerializer):
class Meta:
model = SignUpDetails
fields = (
'first_name',
'last_name',
'email',
'username',
'password',
)
extra_kwargs = {
'email': {
'validators': [UniqueValidator(queryset=SignUpDetails.objects.all())]
}
}
Теперь сериализатор будет проверять, уникален ли email, и выдавать ошибку в противном случае. Таким образом, вам следует не делать валидацию в представлении, это относится к уровню сериализации.
Вариант 2: Указание уникальности для поля электронной почты
Если вы определили свою собственную модель пользователя, вы можете сделать поле email также уникальным, тогда модель пользователя будет выглядеть следующим образом:
from django.db import models
from django.contrib.auth.models import AbstractUser
class SignUpDetails(AbstractUser):
email = models.EmailField(
_('email address')
unique=True
)
# …