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

如何在Django用户应用中实现添加、拒绝、删除好友及好友申请功能

Django好友系统实现方案

1. 修改models.py

在原有代码基础上新增好友关系字段和好友申请表单:

from django.db import models
from django.contrib.auth.models import User
from PIL import Image

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')
    # 新增好友多对多字段,symmetrical=True表示好友关系双向生效
    friends = models.ManyToManyField("self", symmetrical=True, blank=True)
    
    def __str__(self):
        return f'{self.user.username} Profile'
    
    def save(self, *args, **kwargs):
            super().save(*args,**kwargs)

            img = Image.open(self.image.path)

            if img.height > 300 or img.width > 300:
                output_size = (300, 300)
                img.thumbnail(output_size)
                img.save(self.image.path)

# 新增好友申请表
class FriendRequest(models.Model):
    STATUS_CHOICES = (
        ('pending', '待处理'),
        ('accepted', '已接受'),
        ('rejected', '已拒绝'),
    )
    from_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sent_requests')
    to_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='received_requests')
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('from_user', 'to_user') # 避免重复发送申请
        ordering = ['-created_at']

    def __str__(self):
        return f'{self.from_user.username} -> {self.to_user.username} ({self.status})'

修改完成后执行迁移命令生效:

python manage.py makemigrations
python manage.py migrate

2. 新增views.py视图函数

在原有视图代码基础上新增好友功能对应的逻辑:

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
from .models import FriendRequest

# 原有视图代码保持不变
def register(request):
    # 原有逻辑不变
    ...

@login_required
def profile(request):
    # 原有逻辑不变
    ...

# 新增:用户列表页,用于查找可添加的好友
@login_required
def user_list(request):
    users = User.objects.exclude(id=request.user.id)
    # 提前获取当前用户的好友ID和已发送申请的用户ID,方便模板判断状态
    friend_ids = request.user.profile.friends.values_list('user_id', flat=True)
    sent_request_ids = FriendRequest.objects.filter(from_user=request.user, status='pending').values_list('to_user_id', flat=True)
    context = {
        'users': users,
        'friend_ids': friend_ids,
        'sent_request_ids': sent_request_ids
    }
    return render(request, 'users/user_list.html', context)

# 新增:发送好友申请
@login_required
def send_friend_request(request, user_id):
    to_user = get_object_or_404(User, id=user_id)
    if request.user == to_user:
        messages.error(request, '不能给自己发送好友申请')
        return redirect('user_list')
    if to_user.profile in request.user.profile.friends.all():
        messages.error(request, '你们已经是好友了')
        return redirect('user_list')
    if FriendRequest.objects.filter(from_user=request.user, to_user=to_user, status='pending').exists():
        messages.error(request, '你已经发送过好友申请,请等待对方处理')
        return redirect('user_list')
    FriendRequest.objects.create(from_user=request.user, to_user=to_user)
    messages.success(request, '好友申请已发送')
    return redirect('user_list')

# 新增:接受好友申请
@login_required
def accept_friend_request(request, request_id):
    friend_request = get_object_or_404(FriendRequest, id=request_id, to_user=request.user, status='pending')
    # 互相添加好友
    request.user.profile.friends.add(friend_request.from_user.profile)
    friend_request.from_user.profile.friends.add(request.user.profile)
    friend_request.status = 'accepted'
    friend_request.save()
    messages.success(request, f'你已和{friend_request.from_user.username}成为好友')
    return redirect('friend_requests')

# 新增:拒绝好友申请
@login_required
def reject_friend_request(request, request_id):
    friend_request = get_object_or_404(FriendRequest, id=request_id, to_user=request.user, status='pending')
    friend_request.status = 'rejected'
    friend_request.save()
    messages.success(request, '已拒绝好友申请')
    return redirect('friend_requests')

# 新增:删除好友
@login_required
def remove_friend(request, user_id):
    friend = get_object_or_404(User, id=user_id)
    if friend.profile in request.user.profile.friends.all():
        request.user.profile.friends.remove(friend.profile)
        friend.profile.friends.remove(request.user.profile)
        messages.success(request, '已删除好友')
    else:
        messages.error(request, '对方不是你的好友')
    return redirect('user_list')

# 新增:好友申请列表页
@login_required
def friend_requests(request):
    requests = FriendRequest.objects.filter(to_user=request.user, status='pending')
    return render(request, 'users/friend_requests.html', {'requests': requests})

3. 配置urls.py路由

在你应用的urls.py中新增对应路由:

from django.urls import path
from . import views

urlpatterns = [
    # 原有路由保持不变
    path('register/', views.register, name='register'),
    path('profile/', views.profile, name='profile'),
    # 新增好友功能路由
    path('users/', views.user_list, name='user_list'),
    path('friend-request/send/<int:user_id>/', views.send_friend_request, name='send_friend_request'),
    path('friend-request/accept/<int:request_id>/', views.accept_friend_request, name='accept_friend_request'),
    path('friend-request/reject/<int:request_id>/', views.reject_friend_request, name='reject_friend_request'),
    path('friend/remove/<int:user_id>/', views.remove_friend, name='remove_friend'),
    path('friend-requests/', views.friend_requests, name='friend_requests'),
]

4. 模板示例

用户列表页(templates/users/user_list.html)

{% extends "base.html" %}
{% block content %}
<h2>用户列表</h2>
<div class="user-list">
    {% for user in users %}
    <div class="card mb-2 p-2">
        <div class="d-flex align-items-center">
            <img src="{{ user.profile.image.url }}" alt="{{ user.username }}" width="40" class="rounded-circle me-3">
            <h5 class="mb-0">{{ user.username }}</h5>
            <div class="ms-auto">
                {% if user.id in friend_ids %}
                    <a href="{% url 'remove_friend' user.id %}" class="btn btn-sm btn-danger">删除好友</a>
                {% elif user.id in sent_request_ids %}
                    <button class="btn btn-sm btn-secondary" disabled>申请已发送</button>
                {% else %}
                    <a href="{% url 'send_friend_request' user.id %}" class="btn btn-sm btn-primary">发送好友申请</a>
                {% endif %}
            </div>
        </div>
    </div>
    {% endfor %}
</div>
{% endblock %}

好友申请列表页(templates/users/friend_requests.html)

{% extends "base.html" %}
{% block content %}
<h2>收到的好友申请</h2>
{% if requests %}
    {% for req in requests %}
    <div class="card mb-2 p-2">
        <div class="d-flex align-items-center">
            <img src="{{ req.from_user.profile.image.url }}" alt="{{ req.from_user.username }}" width="40" class="rounded-circle me-3">
            <h5 class="mb-0">{{ req.from_user.username }} 申请添加你为好友</h5>
            <div class="ms-auto">
                <a href="{% url 'accept_friend_request' req.id %}" class="btn btn-sm btn-success me-2">接受</a>
                <a href="{% url 'reject_friend_request' req.id %}" class="btn btn-sm btn-danger">拒绝</a>
            </div>
        </div>
    </div>
    {% endfor %}
{% else %}
<p>暂无待处理的好友申请</p>
{% endif %}
{% endblock %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 04:06:05