python-3.xdjangodjango-viewsdjango-users

Django User View Affects current_user


I have url for viewing all info about specific user:

blog/urls.py (I'm using 'urlpatterns +=' to give a piece of urlpatterns list, it's not += in my file)

urlpatterns += path('user/<int:pk>/', UserDetailView.as_view(), name='user-detail'),

that uses this UserDetailView View:

blog/views.py

class UserDetailView(DetailView):
    model = User
    template_name = 'blog/user_detail.html'

that inherits from DetailView and uses Django's User model.

I have navbar in base html file that displays current user nickname with link to their page attached to it:

base.html(which all other html files inherit from)

{% if user.is_authenticated %}
                        <a class="nav-item nav-link" href="{% url 'post-create' %}">New Post</a>
                        <a class="nav-item nav-link" href="{% url 'user-detail' user.id %}">{{ user.username }}</a>
                        <a class="nav-item nav-link" href="{% url 'logout-page' %}">Logout</a>

Now, when I'm logged in and looking any page except 'user/<int:pk>/', nickname with link shows as it should, but when I'm looking some specific user's page, {{ user ]} changes from current user to user who's page I'm looking at: images.

ListView with Post model that calls User by its nickname does not affect current user:

blog/urls.py

urlpatterns += path('user/<str:username>', UserPostListView.as_view(), name='user-posts')

blog/views.py

class UserPostListView(ListView):
    model = Post
    template_name = 'blog/user_posts.html'   # <app>/<model>_<viewtype>.html    # blog/post_list.html
    context_object_name = 'posts'
    paginate_by = 2

    def get_queryset(self):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        return Post.objects.filter(author=user).order_by('-date_posted')


UserPostListView.

Is there a way for me to prevent DetailView with User model from changing {{ user }} from current user to one who's page I'm looking at?


Solution

  • Is there a way for me to prevent DetailView with User model from changing {{ user }} from current user to one who's page I'm looking at?

    The reason this happens is because Django injects the object as object in the template, but also as the result of a .get_context_object_name(…) [Django-doc] which is by default the name of the model in lowercase, so in this case user

    But we can obtain the logged in user as {{ request.user }} instead so:

    {{ request.user }}  # 🖘 logged-in user
    {{ user }}          # 🖘 object of the DetailView
    {{ object }}        # 🖘 object of the DetailView

    Another option is to specify a different context_object_name, like:

    class UserDetailView(DetailView):
        model = User
        template_name = 'blog/user_detail.html'
        context_object_name = 'the_user'

    Then we thus work with:

    {{ request.user }}  # 🖘 logged-in user
    {{ user }}          # 🖘 logged-in user
    {{ the_user }}      # 🖘 object of the DetailView
    {{ object }}        # 🖘 object of the DetailView

    Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation [Django-doc].