友谊关系的最佳模型(在Django中)

时间:2011-12-25 19:28:32

标签: django database models friend social-network-friendship

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

可能的状态是:

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

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

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

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

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

但将朋友与friendrequest关系合并似乎相当不洁净。如果没有这种合并,数据就是多余的,因为那时“A.friends中的A而不是A.friends中的B”将是未定义的状态。

朋友查询:A.friends.filter(friends__contains = B)#rather在数据库级别进行复杂查找,对编码人员不直观

单独表格

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表

另一种选择是具有朋友字段的朋友模型,这是一个很多的字段,它恰好链接到两个人。然后,选择匹配朋友字段中的一个人,然后返回模型,其中可以通过从朋友集中减去A来提取人B.但这样做太过分了,因为没有朋友对象会有超过2个人关联。

朋友查询:Friendship.objects.filter(persons__contains = A)#queries两个表

那么,您认为存储友谊关系的最简洁,最直观的解决方案是什么?有没有共同的模式怎么做?

3 个答案:

答案 0 :(得分:1)

如果您不想重新实现所有这些“友谊”关系,则可以使用以下模块: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')

它还提供跟踪,阻止和相关的经理。

答案 1 :(得分:0)

对于sql db,我会使用多对多的关系。但如果您认为您将拥有大量用户,您可能需要考虑像flock-db这样专门为此类数据设计的图形数据库

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

(保留sql db上的常规数据并保持图数据库之间的关系)

答案 2 :(得分:0)

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

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