You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在每篇帖子上显示对应发帖用户的好友请求按钮?

如何在每篇帖子上显示对应发帖用户的好友请求按钮?

看起来你现在的核心问题是视图逻辑和模板循环完全没对应上——你在视图里给所有非当前用户的Profile生成了按钮状态,但模板里却把所有用户的按钮都套在了每篇帖子下面,这就导致按钮要么重复显示要么和发帖人不匹配,自然没法正确显示对应每个发帖用户的按钮。我帮你梳理下问题点,再给出修复后的代码:

问题出在哪?

  1. 数据关联错误:你视图里生成的profile_and_button_status是所有非当前用户的Profile集合,但没有和每篇Post的作者绑定。模板里循环帖子时又嵌套循环所有用户的按钮,这就导致每篇帖子下面会显示所有用户的按钮,完全和发帖人不搭边。
  2. 逻辑冗余:你处理了所有非当前用户的Profile,但其实只需要针对每篇帖子的作者来判断按钮状态就行,没必要处理无关用户。
  3. 字段命名混淆:Post模型里的poster_profile字段是关联到用户的,但名字很容易和Profile模型搞混,后面可以改成author更清晰。

修复后的视图代码

重新调整逻辑,针对每篇帖子的作者生成对应的按钮状态,避免处理无关用户:

from django.db.models import Q

def ForYouView(request):
    page_title = "For You"
    # 获取所有帖子,预加载作者,减少数据库查询次数
    posts = Post.objects.all().select_related('poster_profile')
    # 用来存储帖子和对应作者的按钮状态
    post_button_data = []
    
    for post in posts:
        post_author = post.poster_profile
        # 如果帖子是当前用户自己发的,按钮状态设为self(不显示按钮)
        if post_author == request.user:
            post_button_data.append((post, 'self'))
            continue
        
        # 1. 判断当前用户和发帖人是否是好友
        is_friend = Profile.objects.filter(
            user=request.user,
            friends__user=post_author
        ).exists()
        
        button_status = 'none'  # 默认是好友状态,显示"已关注/好友"
        if not is_friend:
            # 2. 判断是否已经给对方发过好友请求
            sent_request = FriendRequest.objects.filter(
                from_user=request.user,
                to_user=post_author
            ).exists()
            # 3. 判断是否收到对方的好友请求
            received_request = FriendRequest.objects.filter(
                from_user=post_author,
                to_user=request.user
            ).exists()
            
            if sent_request:
                button_status = 'cancel_request_sent'
            elif received_request:
                button_status = 'follow_back_request'
            else:
                button_status = 'not_friend'
        
        post_button_data.append((post, button_status))
    
    context = {
        'page_title': page_title,
        'post_button_data': post_button_data,
    }
    return render(request, 'foryou.html', context)

修复后的模板代码

模板里直接循环post_button_data,每个元素就是单篇帖子+对应作者的按钮状态,完美匹配:

{% if post_button_data %}
    {% for post, button_status in post_button_data %}
        <div class="post-card">
            <!-- 显示发帖人信息 -->
            <div class="post-author">@{{ post.poster_profile.username }}</div>
            <!-- 显示帖子内容 -->
            <div class="post-content">{{ post.caption }}</div>
            
            <!-- 显示对应按钮 -->
            {% if button_status != 'self' %}
                {% if button_status == 'not_friend' %}
                    <a href="#" class="friend-request-btn">
                        <button type="button" class="btn btn-primary">加好友</button>
                    </a>
                {% elif button_status == 'cancel_request_sent' %}
                    <a href="#" class="friend-request-btn">
                        <button type="button" class="btn btn-secondary">取消请求</button>
                    </a>
                {% elif button_status == 'follow_back_request' %}
                    <a href="#" class="friend-request-btn">
                        <button type="button" class="btn btn-success">同意加好友</button>
                    </a>
                {% elif button_status == 'none' %}
                    <button type="button" class="btn btn-outline-secondary" disabled>已成为好友</button>
                {% endif %}
            {% endif %}
        </div>
    {% endfor %}
{% else %}
    <p class="empty-tip">暂时还没有帖子哦~</p>
{% endif %}

额外小建议

  1. 把Post模型里的poster_profile字段改成author,这样代码可读性会高很多,避免和Profile模型混淆。
  2. exists()代替len(...) == 1来判断请求是否存在,exists()是数据库层面的判断,比把数据查出来再取长度高效多了。
  3. 视图里的select_related('poster_profile')很重要,能减少循环里的数据库查询次数,避免性能问题。

内容来源于stack exchange

火山引擎 最新活动