使用中介模型时models.ManyToManyField的作用及两种关注实现方案差异
Django 关注关联实现疑问解答
1. 用中介模型时,ManyToManyField的作用和必要性
带来的益处
- 能用上Django ORM原生的多对多便捷操作:比如直接调用
user.follow.add(目标用户)完成关注,user.follow.all()获取所有关注的人,user.follow.remove(目标用户)取消关注,不用自己写复杂的查询语句去操作Follow表。 - 模型关系更直观:从CustomUser模型一眼就能看出存在“关注”的多对多关联,语义更清晰。
- ORM查询整合更顺畅:后续做关联查询时,能和Django的多对多查询逻辑无缝衔接,减少额外的代码编写。
是否是必需项?
不是必需的。就算不定义这个字段,只靠Follow中介模型也能实现关注功能——比如用Follow.objects.create(user=用户A, following=用户B)来创建关注关系,通过用户A.following.all()(依赖Follow模型里的related_name)获取关注列表。但代价是失去了上面说的ORM便捷操作,所有关系操作都得手动写代码处理。
2. 只用基础User模型的话,是否需要自定义CustomUser?两种方案差异
是否有必要自定义?
完全没必要。如果你的项目不需要给User模型加额外字段或功能,只是实现关注关联,直接用方案二就行,多定义一个CustomUser纯粹是增加不必要的复杂度。
两种方案的具体差异
- 模型结构:
方案一多了一个继承自AbstractUser的CustomUser模型,还得在settings.py里配置AUTH_USER_MODEL = '你的应用名.CustomUser';方案二直接复用系统自带的User模型,不用额外配置。 - 操作便捷性:
方案一可以用user.follow.add()这类原生多对多方法快速操作关注关系;方案二必须通过Follow.objects.create/delete来手动创建或删除关注记录,查询粉丝/关注列表只能靠Follow模型里定义的related_name(比如user.followers.all())。 - 扩展性:
方案一如果后续要给User加字段(比如头像、个人签名),直接在CustomUser里加就行,不用改关注逻辑;方案二如果之后要扩展User模型,就得重构为自定义User,还得迁移已有数据,成本更高。 - 语义清晰度:
方案一从User模型本身就能看到“follow”关联,别人看代码时更容易理解关系;方案二的关注关系只存在于Follow模型里,User模型本身看不出和关注功能的关联。
方案一代码
class CustomUser(AbstractUser): follow = models.ManyToManyField( 'self', through='Follow', symmetrical=False ) class Follow(models.Model): user = models.ForeignKey( CustomUser, on_delete=models.CASCADE, related_name='followers' ) following = models.ForeignKey( CustomUser, on_delete=models.CASCADE, related_name='following' ) created = models.DateTimeField( 'Creation Time', auto_now_add=True, null=True )
方案二代码
User = get_user_model() class Follow(models.Model): user = models.ForeignKey( User, on_delete=models.CASCADE, related_name='followers' ) following = models.ForeignKey( User, on_delete=models.CASCADE, related_name='following' ) created = models.DateTimeField( 'Creation Time', auto_now_add=True, null=True )
内容的提问来源于stack exchange,提问作者Artem Balanov
相关产品推荐
相关产品推荐

