Create user inactive as default (is_active default False)

  1. Avoid modifying built-ins. There are better ways to do things.
  2. Like signals. Signals are awesome.
  3. In this case, I'd attach to the pre_save signal of django.contrib.auth.models.User, and manually correct the is_active property of the model instance (if the object is new).
  4. This way, you can add some logic to make sure you're properly marking a user as not active.
  5. Because user's added within the Admin should probably be active, if the admin marks them as active.

jack_shed suggested signals, which helped me find the direction to take it. But there was still work from there to figure out how exactly to test and modify after receiving the signal.

Here's what worked for me.

from django.dispatch import receiver
from django.db.models.signals import pre_save
from django.contrib.auth.models import User

@receiver(pre_save, sender=User)
def set_new_user_inactive(sender, instance, **kwargs):
    if instance._state.adding is True:
        print("Creating Inactive User")
        instance.is_active = False
    else:
        print("Updating User Record")

This will catch the action of creating a user before the save occurs, then test if this instance state is "adding" or not. That differentiates between creating and updating a model instance.

If you don't do this test, updating the user sets is_active to False also, and there ends up being no way to activate them through django.


Elegant solution when using django-allauth.

There is another very nice solution.. one that sounds very much like what you desire.

I have created a custom form (in my case a ModelForm) that I can hand over to django-allauth via the ACCOUNT_SIGNUP_FORM_CLASS setting. What this does.. is ask the new potential user to supply additional fields during the signup process.

That has some very nice advantages:

  1. You can add some fields very elegantly in addition to the default stuff.
  2. It works for both social and "normal" signup.
  3. No patching of 3rd party apps required.
  4. You are still able to modify and maintain everything in the admin.
  5. In the custom form you get access to the new user instance before it gets saved to the database. This means you can even process the provided information do things like create a profile object for him and set the user as inactive ..all in one go. This works because you can check if everything is ok.. and only then commit to do all these steps or reject the form with a validation error. :)

Well.. sounds good right?
But how exactly does it work (i.e. look like)?
I am glad you asked.. ^_^

For your use case it might look something like this:

settings.py

[...]
ACCOUNT_SIGNUP_FORM_CLASS = "<your_app>.forms.SignupForm"
[...]

forms.py

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.is_active = False
        user.save()