Cannot set is_active to False in user manager

Hello,

In my new Django project I have two requirements.

The first one is to have email as username.

This part is fairly easy:

class CustomUserManager(BaseUserManager):
    """
    Create and save a user with the given email and password.
    """

    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError(_('The given email must be set'))

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

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Superuser must have is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Superuser must have is_superuser=True.')

        return self._create_user(email, password, **extra_fields)


class CustomUser(AbstractUser):
    username = None

    email = models.EmailField(_('email address'), unique=True)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

This part works fine without any issues.

The second requirement is to have the new users disabled by default. So I modify the user manager as below:

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        extra_fields.setdefault('is_active', False)
        return self._create_user(email, password, **extra_fields)

Now is_active is set to False.

But this doesn’t work. I create a new user in the Admin site and the Active property is still True.

So I remove the above line and do this instead:

class CustomUser(AbstractUser):
    username = None

    email = models.EmailField(_('email address'), unique=True)

    is_active = models.BooleanField(
        _('active'),
        default=False,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

This solution works, but it’s not productive and I’m also curious why the first approach didn’t work.

1 Like

The UserCreationForm from the admin does not use the manager (and its create_user method) to create a new user. As for any ModelForm, it instantiate the model (User here) and save it. Hence, the default value for is_active is the one set in field declaration, not any override from the manager

1 Like