You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Django的User DetailView覆盖当前用户{{ user }}变量?

问题描述

我配置了查看特定用户信息的URL:
blog/urls.py(示例用urlpatterns +=展示片段,实际文件中并非如此)

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

对应的视图:
blog/views.py

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

该视图继承自DetailView,使用Django的User模型。

在所有页面继承的base.html导航栏中,设置了显示当前用户昵称并链接到其个人页面:
base.html

{% 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>
{% endif %}

问题:登录后,除user/<int:pk>/页面外,导航栏用户昵称显示正常;但访问特定用户页面时,{{ user }}会从当前用户变为所查看页面的用户。

对比调用User的Post模型ListView不会影响当前用户:
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'
    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')

请问如何避免Django的User DetailView将模板中的{{ user }}从当前用户替换为所查看的用户?


解决方法

方法1:修改DetailView的context_object_name

Django的DetailView默认会把查询到的模型实例以模型类名小写的形式传入模板上下文,这里模型是User,所以默认会覆盖模板中原本代表当前登录用户的user变量。

只需要给UserDetailView指定一个自定义的context_object_name,比如viewed_user:

class UserDetailView(DetailView):
    model = User
    template_name = 'blog/user_detail.html'
    context_object_name = 'viewed_user'  # 新增这一行

之后在user_detail.html模板中,用{{ viewed_user }}指代当前查看的用户,导航栏里的{{ user }}依然是当前登录用户。

方法2:在模板中直接使用request.user

如果不想修改视图代码,可以直接在base.html的导航栏里用{{ request.user }}代替{{ user }},确保始终获取当前登录用户:

{% if request.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' request.user.id %}">{{ request.user.username }}</a>
    <a class="nav-item nav-link" href="{% url 'logout-page' %}">Logout</a>
{% endif %}

注意:需确保项目配置中'django.contrib.auth.middleware.AuthenticationMiddleware'中间件已启用,这样request.user才能在模板中正常访问。

方法3:重写get_context_data方法

也可以通过重写UserDetailView的get_context_data方法,明确保留当前登录用户的上下文变量,同时自定义查看用户的变量名:

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

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 将查询到的用户重命名为viewed_user
        context['viewed_user'] = context.pop('user')
        # 确保当前登录用户以current_user存在
        context['current_user'] = self.request.user
        return context

之后模板里用{{ viewed_user }}显示被查看的用户,{{ current_user }}或{{ user }}显示当前登录用户。


内容的提问来源于stack exchange,提问作者lumba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:15:16