Search code examples
djangodjango-users

How to prevent user to be both of types?


I have a model like from this answer:

class MyUser(AbstractUser):
    is_student = models.BooleanField(default=False)
    is_teacher = models.BooleanField(default=False)

Is it possible to prevent create new user both of types simultaneously at model level? In other words, it could be ONLY is_student == False and is_teacher == True or vise versa.


Solution

  • As far as I know, you can't have multiple User models with different properties. Django can only have one User model. If the only change you need is that one of the fields need to be gone, my best bet would be to just ignore the field when you need to. For example, when a student wants to sign up they click on a "Sign up as a student" link, where you just omit the is_teacher field from the form and vice versa when it is a teacher.

    An example of this could be:

    User model:

    class User(AbstractUser):
        """User model."""
        username = models.CharField(max_length=75, unique=True)
        email = models.EmailField(_('email address'), unique=True)
        is_student = models.BooleanField(default=False)
        is_teacher = models.BooleanField(default=False)
    
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = ['username']
    
        objects = UserManager()
    
        def __str__(self):
            """Return a string representation of the user."""
            string_repr = str(self.username) + ' (' + str(self.email) + ')'
    
            return string_repr
    

    UserCreationForm model (for both student and teacher):

    class CreateUserStudentForm(UserCreationForm):
        # Require the email field.
        email = forms.EmailField(required=True)
    
        class Meta:
            model = User
            fields = ("email", "username", "is_student", "password1", "password2")
    
        def clean_email(self):
            data = self.cleaned_data['email']
            return data.lower()
    
        def save(self, commit=True):
            user = super(UserCreationForm, self).save(commit=False)
            # Get all the relevant data, and save it.
            user.email = self.clean_email()
            user.username = self.cleaned_data["username"]
            user.is_student = self.cleaned_data["is_student"]
            user.set_password(self.cleaned_data['password1'])
    
            # Save the newly created user.
            if commit:
                user.save()
            return user
    
    class CreateUserTeacherForm(UserCreationForm):
        # Require the email field.
        email = forms.EmailField(required=True)
    
        class Meta:
            model = User
            fields = ("email", "username", "is_teacher", "password1", "password2")
    
        def clean_email(self):
            data = self.cleaned_data['email']
            return data.lower()
    
        def save(self, commit=True):
            user = super(UserCreationForm, self).save(commit=False)
            # Get all the relevant data, and save it.
            user.email = self.clean_email()
            user.username = self.cleaned_data["username"]
            user.is_teacher = self.cleaned_data["is_teacher"]
            user.set_password(self.cleaned_data['password1'])
    
            # Save the newly created user.
            if commit:
                user.save()
            return user