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

Django好友请求功能报错及按钮状态异常问题求助

解决你的Django好友请求功能问题

嘿,我来帮你搞定这两个Django开发里的问题,顺便解决模板循环的疑问!

1. 修复"QuerySet object has no attribute user"报错

这个报错的根源很明确:你在视图里的p = Profile.objects.exclude(user=request.user)得到的是一个QuerySet(多个Profile对象的集合),而不是单个Profile实例。你直接写u = p.user,相当于给整个集合找user属性,QuerySet当然没有这个属性啦!

另外你的代码里还有几个小拼写错误:from_uset应该是from_user,context里的'sent_request',:sent_request多了个逗号,这些都得先修正。

2. 实现每个按钮独立切换状态

你现在的按钮状态是全局的button_status变量,所有用户共用同一个状态,自然会出现点第一个按钮所有按钮都变的情况。正确的做法是给每个Profile单独计算对应的按钮状态,然后把“Profile+状态”的组合传到模板里。

修改后的视图函数

def home(request):
    # 获取当前用户之外的所有Profile(这是一个QuerySet)
    profiles = Profile.objects.exclude(user=request.user)
    profile_and_button_status = []
    
    for profile in profiles:
        button_status = 'not_friend'  # 默认状态
        
        # 检查是否已经是好友
        if profile in request.user.profile.friends.all():
            button_status = 'is_friend'
        else:
            # 检查当前用户是否已给该用户发过请求
            if FriendRequest.objects.filter(from_user=request.user, to_user=profile.user).exists():
                button_status = 'add_request'
            # 检查该用户是否给当前用户发过请求
            elif FriendRequest.objects.filter(from_user=profile.user, to_user=request.user).exists():
                button_status = 'cancel_request'
        
        # 把每个Profile和对应的状态打包成元组,加入列表
        profile_and_button_status.append( (profile, button_status) )
    
    context = {
        'profile_and_button_status': profile_and_button_status,
    }
    return render(request, 'home.html', context)

修改后的模板代码

现在模板里循环每个“Profile+状态”的组合,每个按钮用自己对应的状态,就不会互相影响了:

{% for profile, button_status in profile_and_button_status %}
    <div class="user-card">
        {{ profile.user.username }}  <!-- 显示用户名 -->
        
        {% if button_status == 'not_friend' %}
            <a href="{% url 'send_friend_request' profile.user.id %}">Add Friend</a>
        {% elif button_status == 'add_request' %}
            <a href="{% url 'cancel_friend_request' profile.user.id %}">Cancel Request</a>
        {% elif button_status == 'cancel_request' %}
            <a href="{% url 'accept_friend_request' profile.user.id %}">Accept Request</a>
        {% elif button_status == 'is_friend' %}
            <span>Already Friends</span>
        {% endif %}
    </div>
{% endfor %}

3. 让模板循环执行两次的正确写法

你原来的写法逻辑有问题,forloop.counter是在循环内部才有效的,要让同一个列表循环两次,直接写两个独立的for循环就行:

<!-- 第一次循环 -->
{% for data in profile_and_button_status %}
    {{ data.0.user.username }}
    <!-- 这里放第一次循环的其他代码 -->
{% endfor %}

<!-- 第二次循环 -->
{% for data in profile_and_button_status %}
    {{ data.0.user.username }}
    <!-- 这里放第二次循环的其他代码 -->
{% endfor %}

如果是需要基于某些条件只循环两次(比如只取前两个元素),可以用slice过滤器:

{% for data in profile_and_button_status|slice:":2" %}
    {{ data.0.user.username }}
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 22:12:50