Django User Is Logged Out outside the home page

I have a django website. Now the problem is, after I sign in as a User or an Agent, the correct links only show up on my home page. Whenever I visit another page, the correct links are gone and are replaced with ‘Sign In’ and ‘Agent Sign In’. Somehow the user is logged out outside of the home page. Now what can I do?

My models.py:

class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)
    groups = models.ManyToManyField(Group, related_name='CustomUser_set', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.')
    user_permissions = models.ManyToManyField(Permission, related_name='customuser_set', blank=True, help_text='Specific permissions for this user.')
    is_user = True

class Profile(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
    phonenumber = models.IntegerField()

    def __str__(self):
        return f'{self.user.username} Profile'



class Agent(AbstractUser):
    username = models.CharField(max_length=100, unique=True)
    name = models.CharField(max_length=100)
    agent_email = models.CharField(max_length=100, unique=True)
    password = models.CharField(max_length=200)
    image = models.ImageField(upload_to = 'Images/')
    bio = models.TextField()
    instagram = models.URLField(max_length=100)
    twitter = models.URLField(max_length=100)
    facebook = models.URLField(max_length=100)
    linkedin = models.URLField(max_length=100)
    is_featured = models.BooleanField(default = False)
    last_login = models.DateTimeField(auto_now_add=True)
    is_active = models.BooleanField(default=True)
    slug = AutoSlugField(populate_from='name')
    is_staff = models.BooleanField(default=False)
    groups = models.ManyToManyField(Group, related_name='agent_set', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.')
    user_permissions = models.ManyToManyField(Permission, related_name='agent_set', blank=True, help_text='Specific permissions for this user.')
    
    is_agent = True
    USERNAME_FIELD = 'username'
    EMAIL_FIELD = 'agent_email'

    def get_absolute_url(self):
        return reverse('agent-dashboard', kwargs={'slug': self.slug})

    class Meta:
        verbose_name_plural = 'Agents'

    def __str__(self):
        return f'Agent {self.name}'

My forms.py:

User = get_user_model() 

class UserSignInForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        if not isinstance(user, User):
            raise forms.ValidationError(
                "This form is for User login only")
        return super().confirm_login_allowed(user)

class AgentSignInForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        if not isinstance(user, Agent):
            raise forms.ValidationError(
                "This form is for Agent login only")
        return super().confirm_login_allowed(user)

My backends.py:

User = get_user_model()

class UserAuthBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(username__iexact=username) | Q(email__iexact=username))
        except User.DoesNotExist:
            return None
        
        if user.check_password(password):
            return user
        return None

class AgentAuthBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            agent = Agent.objects.get(Q(username=username) | Q(agent_email=username)) 
        except Agent.DoesNotExist:
            return None
        
        if agent.check_password(password):
            return agent
        return None

My middleware.py:

class AgentAuthenticationMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if hasattr(request, 'user') and request.user.is_authenticated and isinstance(request.user, Agent):
            request.user = request.user
        response = self.get_response(request)
        return response

My signals.py:

@receiver(user_logged_in)
def user_logged_in_callback(sender, request, user, **kwargs):
    if isinstance(user, Agent):
        request.user = user

My AgentLoginView and UserLoginView:

class UserLoginView(LoginView):
    authentication_backend = "users.backends.UserAuthBackend"
    template_name = 'users/login.html'
    form_class = UserSignInForm

    def form_valid(self, form):
        print("Before login, request.user:", self.request.user)
        
        agent = form.get_user()
        # Set the authentication backend before login
        agent.backend = self.authentication_backend
        login(self.request, agent)
        self.request.session['is_agent'] = True
        self.request.session['user_type'] = 'user'
        self.request.session['is_authenticated'] = self.request.user.is_authenticated
        print("After login, request.user:", self.request.user)

        return redirect('home')

class AgentLoginView(LoginView):
    authentication_backend = "users.backends.AgentAuthBackend"
    template_name = 'users/agent_login.html'
    form_class = AgentSignInForm

    def form_valid(self, form):
        print("Before login, request.user:", self.request.user)
        
        agent = form.get_user()
        # Set the authentication backend before login
        agent.backend = self.authentication_backend
        login(self.request, agent)
        self.request.session['is_agent'] = True
        self.request.session['user_type'] = 'agent'
        self.request.session['user_slug'] = agent.slug
        self.request.session['is_authenticated'] = self.request.user.is_authenticated
        print("After login, request.user:", self.request.user)

        return redirect('home')

My home view:

def home(request):
    agents = Agent.objects.all()
    properties = Property.objects.all()

    # Check if the user is authenticated and retrieve user information
    is_agent = request.session.get('user_type') == 'agent'
    user_slug = request.session.get('user_slug')

    # Retrieve the full user object using the stored information
    user = Agent.objects.get(slug=user_slug) if is_agent and user_slug else None
    
    is_authenticated = request.session.get('is_authenticated')
    # Print debugging statements
    print(f"User: {user}")
    print(f"Is Agent: {is_agent}")

    context = {'agents': agents, 'properties': properties, 'is_agent': is_agent, 'user': user, 'is_authenticated': is_authenticated}
    return render(request, 'blog/index.html', context)

My base.html:

{% if is_authenticated %}
  {% if is_agent %}
    <li><a href="{% url 'agent-dashboard' user.slug %}">Dashboard</a></li>
    <li><a href="{% url 'agent-sign-out' %}">Agent Sign Out</a></li>
  {% else %}
    <li><a href="{% url 'profile' %}">Profile</a></li>
    <li><a href="{% url 'logout' %}">Sign Out</a></li>
  {% endif %}
{% else %}
  <li><a href="{% url 'login' %}">Sign In</a></li>
  <li><a href="{% url 'agent-sign-in' %}">Agent Sign In</a></li>
{% endif %}

This is not going to do what you think it’s going to do.

It looks like you’re trying to have two different User models in your project. This is a bad idea and is going to be extremely difficult to make work properly and reliably.

You should have one User model, with as many “profile” or “attribute” classes as necessary for additional information to be stored and referenced appropriately.

Fix your User model structure.

Sir, I am actually here to seek advice because I’m new to Django. I didn’t know that having two user models would be a bad idea. All I want is for Users to log in properly and see the User Logout and User Profile links on the navbar and for Agents to log in and see the correct links. I don’t know how to do that. I don’t want Agents to have to register as a User first. I want Agents and Users to have separate Login and register pages.

Can you suggest me how to do that? Or is Django not good enough for this functionality?

An “Agent” is a type of “User” - not something different.

Any person that logs on is a “User”. Whatever other characteristics that User may have is a separate issue.

You can have multiple login and registration pages, each with their own url. That’s got nothing to do with the type of person logging in.

An Agent is a User.

Don’t confuse how you structure your project internally with what is exposed to the outside world.

You will want to build your project according to how Django expects it to be, and then build the UI for what the users see.

So the solution here is to extend the User model for Agents, that way an Agent would have to register as a User first and then login using the same login url as Users?

I don’t think you can have 2 User instances in one projects. Make them models with the same User Model Foreign Key.

Not quite.

The solution here is to use a “profile” model to identify the “Agent-specific” data associated with a “User”

You really need to erase this idea from your mind that “Users” and “Agents” are in any way different. An Agent is a User - with (potentially) some additional information.

No, I answer that above:

You can give one login URL to “non-Agents” and a different login URL to “Agents”.

Can you fix my code please? I think I am lost.

Can you fix my code please? I think I am lost. I have been trying to fix it for the last month, but you are right, having two separate user models is an extremely difficult thing to pull off. I almost quit several times.

Start by refactoring your code to eliminate all usage of the Agent model as if it were a User.

Get your login and home page functional with the “base case” first.

Sorry, could you please show me what changes need to be made to my code for it to work? Like edit my code to be the correct code? Would be a great help and I’d be grateful for you help forever. Thank you.

No, I’m sorry. It’s your project. If you’re looking for someone to write your code for you, I suggest you hire someone.