Django Custom User Model - "The given username must be set" Error in Registration View

I'm working on a Django registration flow where users receive a tokenized link to complete their registration. During the process, I associate a UserProfile instance with the user using get_or_create(). However, I encounter an error stating that the username must be set.

from django.contrib.auth import get_user_model
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_decode
from django.shortcuts import render, redirect
from django.contrib import messages
from .models import UserProfile
from .forms import RegistrationForm

User = get_user_model()

def complete_registration_step1(request, uidb64, token):
    try:
        uid = urlsafe_base64_decode(uidb64).decode()
        user = User.objects.get(pk=uid)

        # Check if the token is valid and hasn't been used
        if user.token_used or not default_token_generator.check_token(user, token):
            messages.error(request, "The confirmation link is invalid or expired.")
            return redirect('home')

    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user is not None:
        if request.method == 'POST':
            form = RegistrationForm(request.POST)
            if form.is_valid():
                user_profile, created = UserProfile.objects.get_or_create(user=user)  # Error occurs here
                
                form_instance = form.save(commit=False)
                user_profile.first_name = form_instance.first_name
                user_profile.birth_date = form_instance.birth_date
                user_profile.gender = form_instance.gender
                user_profile.save()

                messages.success(request, "First step of registration completed.")
                # return redirect('complete_registration_step2', uidb64=uidb64, token=token)
        else:
            form = RegistrationForm()

        return render(request, 'registration/complete_registration.html', {'form': form})
    else:
        messages.error(request, "User does not exist.")
        return redirect('home')
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models

class CustomUserManager(BaseUserManager):
    def create_user(self, email, username=None, password=None, **extra_fields):
        if not email:
            raise ValueError("Email is required")
        if not username:
            username = email

        email = self.normalize_email(email)
        user = self.model(email=email, username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)
        return self.create_user(email, username, password, **extra_fields)

class CustomUser(AbstractUser):
    username = models.CharField(max_length=150, unique=True, blank=True, null=True)
    email = models.EmailField(unique=True)
    
    objects = CustomUserManager()

    def save(self, *args, **kwargs):
        if self.email and not self.username:
            self.username = self.email
        super().save(*args, **kwargs)
class UserProfile(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100, blank=True, null=True)
    birth_date = models.DateField(blank=True, null=True)
    gender = models.CharField(max_length=10, blank=True, null=True)

ValueError: The given username must be set

  • UserProfile is correctly linked to CustomUser with a OneToOneField.

  • The username field in CustomUser is optional, and I expect it to be set automatically using the email field.

  • The error occurs at UserProfile.objects.get_or_create(user=user), but I'm unsure why it's causing an issue with username.

How can I fix this issue and ensure the user can complete registration properly?

Request Method:POST

Django Version:5.1.3

Exception Type:ValueError

Exception Value:The given username must be set

Thanks

Вернуться на верх