Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django error: UNIQUE constraint failed: auth_user.username

I need to register a user by sending an activation token to her Email address. I am getting this error (UNIQUE constraint failed: auth_user.username) when trying to register her using custom built-in functions register and activate.

My code is as follows:

forms.py

class UserRegisterForm(forms.Form, UserCreationForm):

username = forms.CharField(max_length=20)
date_of_birth = forms.DateField(widget=forms.SelectDateWidget(years=range(2017, 1900, -1)))
email = forms.EmailField()

def clean_username(self):
    username = self.cleaned_data.get('username')
    if User.objects.filter(username__iexact=username).exists():
        raise forms.ValidationError('Username already exists')
    return username

def clean_date_of_birth(self):
    '''
    Only accept users aged 13 and above
    '''
    userAge = 13
    dob = self.cleaned_data.get('date_of_birth')
    today = date.today()
    if (dob.year + userAge, dob.month, dob.day) > (today.year, today.month, today.day):
        raise forms.ValidationError('Users must be aged {} years old and above.'.format(userAge))
    return dob

def clean_email(self):
    email = self.cleaned_data.get('email')
    if User.objects.filter(email__iexact=email).exists():
        raise forms.ValidationError('A user has already registered using this email')
    return email

def clean_password2(self):
    '''
    we must ensure that both passwords are identical
    '''
    password1 = self.cleaned_data.get('password1')
    password2 = self.cleaned_data.get('password2')
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError('Passwords must match')
    return password2

views.py

def register(request):
if request.method == 'POST':
    form = UserRegisterForm(request.POST)
    if form.is_valid():
        username = form.cleaned_data.get('username')
        email = form.cleaned_data.get('email')
        password = form.cleaned_data.get('password1')
        new_user = User.objects.create(username=username, email=email, password=password)
        new_user = form.save(commit=False)
        #new_user.set_password(password) # hashes the password
        new_user.is_active = False
        new_user.save()
        current_site = get_current_site(request)
        message = render_to_string('email_activation_link.html', {
            'new_user':new_user,
            'domain':current_site.domain,
            'uid': urlsafe_base64_encode(force_bytes(new_user.pk)),
            'token': account_activation_token.make_token(new_user),
        })
        mail_subject = 'Activate your Frac account.'
        #to_email = form.cleaned_data.get('email')
        email = form.cleaned_data.get('email')
        to_email = EmailMessage(mail_subject, message, to=[email])#[to_email])
        to_email.send()
        return render(request, 'register_confirm.html', {'form': form})
else:
    form = UserRegisterForm()

return render(request, 'register.html', {'form': form})

spec_backend = 'django.contrib.auth.backends.ModelBackend'


def activate(request, uidb64, token):
try:
    uid = force_text(urlsafe_base64_decode(uidb64))
    new_user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
    new_user = None
if new_user is not None and account_activation_token.check_token(new_user, token):
    new_user.is_active = True
    new_user.save()
    return render(request, 'register_complete.html', {})
else:
    return render(request, 'registration_incomplete.html', {})

What is causing such an error? I researched similar posts on this platform but each case is unique.

like image 869
Dr. Younes Henni Avatar asked Nov 16 '17 10:11

Dr. Younes Henni


2 Answers

You are getting the unique constraint error because you are trying to create the same user twice:

new_user = User.objects.create(username=username, email=email, password=password)
new_user = form.save(commit=False)
...
new_user.save()

Since you are using a model form, you don't need to call User.objects.create() manually. Remove that line. You can also remove the three lines above that fetch username, email and password from the cleaned data.

like image 107
Alasdair Avatar answered Oct 19 '22 09:10

Alasdair


No need of such confusing type of answers , here's the simplest one that can be added to views.py, wherever you have handled your signup form.

It will just show the error without showing the default
(*Dont Copy this one)

    UNIQUE constraint failed auth_user.username

Here's the code :-
(*Copy this one)
    if User.objects.filter(username = username).first():
        messages.error(request, "This username is already taken")
        return redirect('home')
like image 3
Lakshyaraj Dash Avatar answered Oct 19 '22 11:10

Lakshyaraj Dash