当前位置:  首页>> 技术小册>> Django框架入门指南

实战项目十三:构建社交网络(一):用户关系

在前面的章节中,我们已经通过Django框架搭建了基础的Web应用,学习了模型(Models)、视图(Views)、模板(Templates)和表单(Forms)等核心概念,并实现了用户注册、登录、个人信息管理等基本功能。本章节,我们将正式踏入社交网络的构建之旅,首先聚焦于“用户关系”这一核心部分,它是任何社交网络不可或缺的基础架构。

引言

社交网络的核心在于用户之间的连接与互动。用户关系通常包括好友关系、关注关系、群组关系等,它们构成了社交图谱的基础。在本项目中,我们将从最简单的“好友关系”入手,实现用户之间的添加好友、删除好友、查看好友列表等功能。

1. 设计用户关系模型

在开始编码之前,我们首先需要设计用户关系的数据库模型。Django的ORM(对象关系映射)允许我们以Python类的方式定义数据库模型,极大简化了数据库操作。

1.1 定义用户模型(如果尚未定义)

通常,Django自带的User模型已经足够用于大多数场景,但如果你需要额外的用户信息(如昵称、头像等),可以通过继承AbstractUser来自定义用户模型。这里我们假设已经有一个包含基本信息的用户模型User

1.2 创建好友关系模型

好友关系可以通过多种方式建模,常见的方法包括使用多对多字段、中间模型(通过自定义模型表示关系)等。为了保持关系的灵活性和可扩展性(比如未来可能需要添加好友关系的创建时间、备注等信息),我们选择使用中间模型。

  1. from django.db import models
  2. from django.contrib.auth.models import User
  3. class Friendship(models.Model):
  4. """
  5. 用户间的好友关系模型
  6. """
  7. from_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friendships_from')
  8. to_user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='friendships_to')
  9. created_at = models.DateTimeField(auto_now_add=True)
  10. # 可以添加更多字段,如备注、关系状态等
  11. class Meta:
  12. unique_together = (('from_user', 'to_user'),) # 确保一对用户之间只存在一种关系
  13. def __str__(self):
  14. return f"{self.from_user} -> {self.to_user}"

这里,Friendship模型包含了两个ForeignKey字段,分别指向User模型,表示关系的发起者和接收者。unique_together元组确保了在数据库中不会存在重复的(from_user, to_user)对,即每个用户只能对另一个用户发起一次好友请求(尽管在实际应用中,我们可能还需要处理请求接受与否的状态)。

2. 实现好友功能

有了模型之后,我们就可以开始实现具体的好友功能了。

2.1 添加好友

添加好友功能通常包括发送好友请求和接受好友请求两个步骤。在这里,我们先实现发送好友请求的功能。

  1. from django.shortcuts import redirect, render
  2. from .models import Friendship
  3. def add_friend(request, user_id):
  4. if request.method == 'POST':
  5. current_user = request.user
  6. target_user = User.objects.get(id=user_id)
  7. # 检查当前用户是否已经向目标用户发送了好友请求或已经是好友
  8. if Friendship.objects.filter(from_user=current_user, to_user=target_user).exists():
  9. return render(request, 'friends/already_friends.html', {'target_user': target_user})
  10. # 发送好友请求
  11. Friendship.objects.create(from_user=current_user, to_user=target_user)
  12. return redirect('user_profile', user_id=target_user.id) # 假设有一个用户资料页的视图
  13. # 如果是GET请求或其他情况,则重定向到用户资料页或其他页面
  14. return redirect('user_profile', user_id=user_id)

注意:在实际应用中,你可能需要为好友请求添加更多的处理逻辑,比如通知机制(通知目标用户有新的好友请求)、好友请求的过期时间等。

2.2 好友请求的接受与拒绝

好友请求的接受与拒绝可以通过更新Friendship模型的状态(虽然在这个简单的模型中我们没有显式地定义状态字段)或创建反向的Friendship记录来实现。这里,我们采用后者作为示例,即当用户接受好友请求时,在数据库中为两个用户之间各自创建一个Friendship记录。

  1. def accept_friend_request(request, friendship_id):
  2. if request.method == 'POST':
  3. friendship = Friendship.objects.get(id=friendship_id)
  4. # 创建反向的Friendship记录以表示双向好友关系
  5. Friendship.objects.create(from_user=friendship.to_user, to_user=friendship.from_user)
  6. # 可选:删除原始的好友请求记录,如果不再需要
  7. # friendship.delete()
  8. return redirect('user_profile', user_id=friendship.from_user.id)
  9. # 错误处理或重定向逻辑
  10. return HttpResponseBadRequest("Invalid request")

注意:在这个示例中,我们没有直接删除原始的好友请求记录,因为有时你可能想要保留历史记录以供将来分析或审计。然而,根据你的应用需求,你可能想要这样做。

2.3 查看好友列表

查看好友列表功能相对简单,只需从当前用户出发,查询所有与之关联的Friendship记录,并获取这些记录的to_user字段即可。

  1. def view_friends(request):
  2. if request.user.is_authenticated:
  3. friends = User.objects.filter(friendships_to__from_user=request.user)
  4. return render(request, 'friends/friends_list.html', {'friends': friends})
  5. else:
  6. return redirect('login') # 未登录用户重定向到登录页面

这里,我们使用了Django的__查询语法来跨关系查询。friendships_to__from_user=request.user意味着查找所有Friendship记录,其中to_user字段对应的Userfriendships_to(即接收到的友谊)中的from_user是当前用户。

3. 视图与模板的整合

上述代码片段展示了如何在Django中处理用户关系的基本逻辑。然而,要让这些功能对用户可见并可用,你还需要创建相应的视图和模板。视图负责处理HTTP请求并调用业务逻辑,模板则负责渲染数据并展示给用户。

在视图中,你将调用上述定义的函数或方法,并处理可能的异常和错误。在模板中,你将使用Django模板语言来展示数据,如好友列表、好友请求状态等。

4. 扩展与考虑

虽然我们已经实现了用户关系的基本功能,但还有许多可以扩展和改进的地方:

  • 好友请求状态:为Friendship模型添加状态字段(如pending, accepted, rejected),以更精细地控制好友请求的流程。
  • 通知系统:实现一个通知系统,当有新的好友请求、好友接受请求等事件发生时,及时通知用户。
  • 性能优化:考虑使用缓存来减少数据库查询次数,提高应用的响应速度。
  • 安全性:确保所有用户操作都经过身份验证和授权,防止未授权访问和篡改。
  • UI/UX:设计直观易用的用户界面,提升用户体验。

通过这些扩展和改进,你的社交网络应用将变得更加健壮、灵活和易用。


该分类下的相关小册推荐: