Add user to a group during creation

Hello everyone. I’m struggling to understand why the following code works using python shell but not using forms.ModelForm. What steps django takes in both scenarios?


from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import Group

# Works from python shell
class CustomUserManager(BaseUserManager):
    def create_user(self, username, email=None, password=None, **extra_fields):
        if email:
            email = self.normalize_email(email)

        user = self.model(username=username, **extra_fields)
        group, _ = Group.objects.get_or_create(name=user.type)
        return user

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

CustomUser model

class CustomUser(AbstractBaseUser, PermissionsMixin):
    class TYPE(models.TextChoices):
        ADMIN = "ADMIN", "Admin"
        STUDENT = "STUDENT", "Student"
        TEACHER = "TEACHER", "Teacher"
        STAFF = "STAFF", "Staff"

    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    username = models.CharField(max_length=100, unique=True)
    date_join = models.DateField(auto_now=True)
    type = models.CharField(max_length=10, choices=TYPE.choices)

    USERNAME_FIELD = "username"
    objects = CustomUserManager()
    default_choice = TYPE.ADMIN

    def save(self, *args, **kwargs):
        if not
            self.type = self.default_choice
        return super().save(*args, **kwargs)

class Student(CustomUser):
    default_choice = CustomUser.TYPE.STUDENT
    # objects = StudentManager()

    class Meta:
        proxy = True

I created a ModelForm for User registration

class UserRegisterForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = (

And finally the view

class UserRegister(View):
    def get(self, request):
        context = {
            "form": UserRegisterForm(),
            "p_form": ProfileForm(),
        return render(request, "users/create_user.html", context)

    def post(self, request):
        type_ = request.POST.get("type")
        if type_ == "STUDENT":
            form = StudentForm(request.POST)
        elif type_ == "STAFF":
            form = StaffForm(request.POST)
        elif type_ == "TEACHER":
            form = TeacherForm(request.POST)
            form = UserRegisterForm(request.POST) # For ADMIN

        p_form = ProfileForm(request.POST)
        if form.is_valid() and p_form.is_valid():
            user =
            return redirect(reverse('login'))
        context = {
            "form": UserRegisterForm(),
            "p_form": ProfileForm(),
        return render(request, "users/create_user.html", context)

What code? Please be specific about what command you’re entering in the shell, and what code you think is in the view that is doing that same thing.

Thanks for your reply.
What I want is to add a user to a specific group based on its type during the creation process, from python shell I can do this

from users.models import CustomUser, Student

s = Student.objects.create_user(username='student1', password='student1') # This will create and add 'student1' to group 'STUDENT'
u = CustomUser.objects.create_user(username='admin', password='admin') # This will create and add 'admin' to 'ADMIN' group

However, using forms.ModelForm a user is created but not added to a group and I’d like to know what I am missing.

What you are missing is that your view isn’t calling the create_user method of the CustomUserManager. You’re calling, which is eventially going to call the model’s save method. But at no time in that process is create_user being called.

Oh, thanks! I’m clear now. If you don’t mind, would you suggest me perhaps an appropriate way of doing this?

Sure, create the group in your view after the user has been created.

1 Like

I can’t thank you enough.