9

为社交网站建模用户之间的友谊的最佳方式是什么?

可能的状态是:

  • 没有友谊
  • A到B的FriendRequest,B需要确认(这个是不对称的)
  • A 和 B 是朋友(这是对称的)

现在选择正确的模型很复杂。

我的朋友是我个人资料的一部分

很明显,A.profile.friends 与其他用户是多对多关系。

  • 没有友谊:B 不在 A.friends 中,A 不在 B.friends 中
  • A请求与B建立友谊:A.friends中的B
  • 朋友:A.friends 中的 B 和 B.friends 中的 A

但是将friend与friendrequest关系合并似乎很不干净。如果没有这种合并,数据是多余的,因为“B.friends 中的 A 而不是 A.friends 中的 B”将是未定义的状态。

Friend-Lookup: A.friends.filter(friends__contains=B) #相当复杂的数据库级别查找,对编码人员来说不直观

单独的表

FriendRequest 很明显,一个有 requester 和 requested_user 的类,选择也很明显。

朋友模型不是很好,因为它会将 person1 和 person2 作为字段,并且所有查找都需要选择具有 person1=A 和 person2=B 或 person1=B 和 person2=A 的朋友

Friend-Lookup: Friend.objects.filter(person1=A) union Friend.objects.filter(person2=A) #unclean 需要联合两个集合

分离 many2many 表

另一种选择是带有friends字段的Friend模型,这是一个many2many字段,它恰好链接到两个人。然后选择匹配朋友字段中的一个人,然后只返回模型,其中可以通过从朋友集中减去 A 来提取人 B。但这太过分了,因为任何朋友对象都不会有超过 2 个关联的人。

Friend-Lookup: Friendship.objects.filter(persons__contains=A) #查询两个表

那么,您认为存储友谊关系最简洁、最直观的解决方案是什么?有没有常见的模式如何做到这一点?

4

3 回答 3

2

如果您不想重新实现所有这些友谊关系的东西,您可以使用以下模块:https ://github.com/revsys/django-friendship

它的行为是您在第三个选项中描述的:它创建单独的 ManyToMany 表。一个用于友谊请求:

class FriendshipRequest(models.Model):
    """ Model to represent friendship requests """
    from_user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='friendship_requests_sent')
    to_user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='friendship_requests_received')

另一个用于友谊状态:

class Friend(models.Model):
    """ Model to represent Friendships """
    to_user = models.ForeignKey(AUTH_USER_MODEL, models.CASCADE, related_name='friends')
    from_user = models.ForeignKey(AUTH_USER_MODEL, models.CASCADE, related_name='_unused_friend_relation')

它还提供关注、阻止和相关管理器。

于 2018-10-21T13:02:49.207 回答
1

我相信这是 Django 支持的扩展多对多关系的一个用例:https ://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

您可以存储其他属性,而不仅仅是存储这些用户之间的连接。这应该很好地将您的问题域投影到数据库模型上。即,一旦两人中的一个人开始建立友谊,就建立您的联系,然后设置额外的字段来存储谁在询问谁以及对方是否接受了友谊。

于 2011-12-25T20:36:08.083 回答
0

对于 sql 数据库,我会为此使用多对多关系。但是如果你认为你会有很多用户你可能想考虑像flock-db这样专门为这种数据设计的图形数据库

http://en.wikipedia.org/wiki/Graph_database

(将常规数据保存在 sql db 上,并在图形数据库上保存关系)

于 2011-12-25T20:32:29.313 回答