Search code examples
djangodetailview

Django User's DetailVew affects authenticated User


I tried to display information about User (profile page) using DetailView. It works but when I open a DetailView of User for some reason Django thinks that I am authenticated as this user. For an example if I log out, open some User's DetailView, Django starts to think that I am logged in as this User. I can see problems as base.html shows currently logged user and changes if user is not authenticated. Any ideas what is wrong? Thanks!

views.py

class ProfileView(DetailView):
    model = User
    template_name = 'users/profile.html'

urls.py

urlpatterns = [
    path('profile/<int:pk>/<str:username>', ProfileView.as_view(), name='profile'),
]

profile.html

{% extends 'base.html' %}
{% block content %}
    <article class = 'media content-section'>
    <div class="media">
        <img class="avatar-image rounded-circle" src="{{ user.profile.image.url }}">
        </div>
    <div class = 'media-body'>
        <div class='article-metadata'>
            <h3>Профиль {{user.username}}</h3>
        </div>
        <div class="article-content">
            <p>{{user.first_name}}</p>
            <p>{{user.email}}</p>
            <p>{{user.profile.birthdate}}</p>
            <p>{{user.date_joined}}</p>
        </div>
    </div>
    </article>
{% endblock %}

base.html

<div class="navbar-nav">
    {% if user.is_authenticated %}
    <div class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    <i class="far fa-user-circle" title="Пользователь"> {{user.username}}</i></a>
...

Solution

  • Actually, the user is not logged in, but an issue with your code. When you are sending the User data to template with context parameter user, it gets mixed up with request.user. And interestingly, if you try with that user (which is sent from DetailView), it will show is_authenticated true, so you would see the logged in user in based html. For example:

    user = User.objects.first()
    user.is_authenticated()  # It will return True
    

    To prevent this, you need to send a different context parameter for DetailView. Like:

    class ProfileView(DetailView):
        context_object_name = "profile_user"
        ...
    

    and in template, use profile_user. Also, if you want only the logged in user to access that particular View, then you should subclass it from LoginRequiredMixin. For example:

    from django.contrib.auth.mixins import LoginRequiredMixin
    
    class ProfileView(LoginRequiredMixin, DetailView):
       ...