AttributeError: 'str' object has no attribute 'ValidationError' Django

Issue

I am trying to create Views.py method where I check if the email already exists in the database. It worked for username but it is not working for emails or tokens. What would be the way to make that possible? Thank you!

@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")

This is the serializer:

class SignUpDetailsForm(serializers.ModelSerializer):
    class Meta:
        model = SignUpDetails
        fields = (
            'first_name',
            'last_name',
            'email',
            'username',
            'password',
        )

It generates AttributeError: ‘str’ object has no attribute ‘ValidationError’

Solution

You can not use raise email.ValidationError(…). email is a string, and a string has no ValidationError attribute. It is also non-sensical, since the variable email does not contain the word email.

Your username is not validated either: that is done by the serializer, and the serializer simply errors on this because the username field of the User model requires the username to be unique. Therefore the serializer will validate this.

Option 1: validating by the serializer

You can implement logic for the email as well. For example by defining your own model, or by adding a UniqueValidator [DRF-doc] to the email serialization field:

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())]
            }
        }

Now the serializer will thus check if the email is unique, and raise an error otherwise. You thus should not do validation in the view, this belongs in the serialization layer.

Option 2: Specifying uniqness for an email field

If you defined your own user model, you can make the email field unique as well, then the user model looks like:

from django.db import models
from django.contrib.auth.models import AbstractUser

class SignUpDetails(AbstractUser):
    email = models.EmailField(
        _('email address')
        unique=True
    )
    # …

Answered By – Willem Van Onsem

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published