Creating a simple multiple users app in Django

So I've created 3 different users: admins, developers, and project managers. When I use the individual signup forms for each of these users and log out, it works, but then I when try to use the login form, it seems to me that it's acting like the signup form. Because when I input the same user details as the one I just created into the login form, it throws up the built-in error message, 'A user with that user name already exists' I'm not sure how to proceed from here.

Here's what I have so far.

models.py

class CustomUser(AbstractUser):
    ACCOUNT_TYPE_CHOICES = (
        ('admin', 'Admin'),
        ('developer', 'Developer'),
        ('project_manager', 'Project Manager')
    )
    account_type = models.CharField(max_length=20, choices=ACCOUNT_TYPE_CHOICES)

login and signupviews

class LoginView(View):
    def get(self, request):
        # Render the login form
        form = LoginForm()
        return render(request, 'users/login.html', {'form': form})

    def post(self, request):
        # Get the form data from the request
        form = LoginForm(request.POST)

        # Validate the form data
        if form.is_valid():
            # Get the username and password from the form
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']

            # Authenticate the user
            user = authenticate(request, username=username, password=password)

            # If the user is authenticated, log them in and redirect to the homepage
            if user is not None:
                login(request, user)
                if user.account_type == 'admin':
                    return redirect('admin_home')
                elif user.account_type == 'developer':
                    return redirect('developer_home')
                elif user.account_type == 'project_manager':
                    return redirect('projectmanager_home')
                return redirect('home')

            # If the user is not authenticated, render the login form again with an error message
            else:
                form.add_error(None, 'Invalid username or password')
                return render(request, 'users/login.html', {'form': form})
        else:
            return render(request, 'users/login.html', {'form': form})

class LogoutView(View):
    def get(self, request):
        # Log out the user and redirect to the login page
        logout(request)
        return redirect('home')
    
class AdminSignUpView(CreateView):
    form_class = AdminSignUpForm
    template_name = 'users/admin_signup.html'
    success_url = '/admin_home/'

    def form_valid(self, form):
        # Create the user and log them in
        user = form.save()
        login(self.request, user)
        return redirect(self.success_url)    
    
class DeveloperSignUpView(CreateView):
    form_class = DeveloperSignUpForm
    template_name = 'users/developer_signup.html'
    success_url = '/developer_home/'

    def form_valid(self, form):
        # Create the user and log them in
        user = form.save()
        login(self.request, user)
        return redirect(self.success_url)
    
class ProjectManagerSignUpView(CreateView):
    form_class = ProjectManagerSignUpForm
    template_name = 'users/projectmanager_signup.html'
    success_url = '/projectmanager_home/'

    def form_valid(self, form):
        # Create the user and log them in
        user = form.save()
        login(self.request, user)
        return redirect(self.success_url)
    

forms.py

class AdminSignUpForm(forms.ModelForm):
    # Define the form fields for the admin sign-up form
    account_type = forms.CharField(max_length=20, widget=forms.HiddenInput(), initial='admin')
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)
    email = forms.EmailField()
    username = forms.CharField(max_length=150)
    password = forms.CharField(max_length=128, widget=forms.PasswordInput())

    class Meta:
        model = CustomUser
        fields = ['first_name', 'last_name', 'email', 'username', 'password']
        
class DeveloperSignUpForm(forms.ModelForm):
    # Define the form fields for the developer sign-up form
    account_type = forms.CharField(max_length=20, widget=forms.HiddenInput(), initial='developer')
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)
    email = forms.EmailField()
    username = forms.CharField(max_length=150)
    password = forms.CharField(max_length=128, widget=forms.PasswordInput())

    class Meta:
        model = CustomUser
        fields = ['first_name', 'last_name', 'email', 'username', 'password']
        
class ProjectManagerSignUpForm(forms.ModelForm):
    # Define the form fields for the admin sign-up form
    account_type = forms.CharField(max_length=20, widget=forms.HiddenInput(), initial='admin')
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)
    email = forms.EmailField()
    username = forms.CharField(max_length=150)
    password = forms.CharField(max_length=128, widget=forms.PasswordInput())

    class Meta:
        model = CustomUser
        fields = ['first_name', 'last_name', 'email', 'username', 'password']
        
class LoginForm(forms.ModelForm):
    class Meta:
        model = CustomUser
        fields = ['username', 'password']
        widgets = {
            'password': forms.PasswordInput(),
        }

Let me know if you need any more information.

I see a few issues in the code that you've shared:

The DeveloperSignUpForm has a hidden field account_type with the initial value of developer, but the ProjectManagerSignUpForm has a hidden field account_type with the initial value of admin. This is incorrect, as the ProjectManagerSignUpForm should have an account_type field with an initial value of project_manager.

The LoginForm has a ModelForm with the model CustomUser, but it does not specify any fields. This means that the form will not have any fields, which may not be the intended behavior. You may want to specify the fields that you want to include in the form, such as username and password.

The CustomUser class has a field account_type with choices defined as a tuple of tuples, but the account_type field in the forms does not use this tuple of choices. Instead, it uses a plain CharField with no choices specified. This means that users will be able to enter any value for the account_type field, regardless of whether or not it is a valid choice. You may want to use a ChoiceField with the choices attribute set to CustomUser.ACCOUNT_TYPE_CHOICES in the forms to ensure that only valid values can be entered.

Back to Top