Как лучше всего моделировать дружеские отношения между пользователями для сайта социальной сети?
Возможные состояния:
- нет дружбы
- FriendRequest от A до B, B необходимо подтвердить (это асимметрично)
- A и B - друзья (это симметрично)
Теперь сложно выбрать правильные модели.
Мои друзья являются частью моего профиля
Совершенно очевидно, что A.profile.friends имеет отношение многих ко многим другим пользователям.
- нет дружбы: B нет у A.friends и A нет у B.friends
- A просит дружбу с B: B у A.friends
- Друзья: B в A.friends и A в B.friends
но, кажется, довольно нечисто объединить друга с отношением дружбы-запроса. и без этого слияния данные являются избыточными, потому что тогда «A в B.friends и не B в A.friends» будет неопределенным состоянием.
Friend-Lookup: A.friends.filter (friends__contains = B) # довольно сложный поиск на уровне БД, не интуитивно понятен для кодеров
Отдельные столы
FriendRequest довольно очевиден, класс с requestter и required_user, выборки тоже вполне очевидны.
Модель друга была бы не очень хороша, потому что в ней были бы поля person1 и person2, и во всех поисках нужно выбрать Friends с person1 = A и person2 = B ИЛИ person1 = B и person2 = A
Friend-Lookup: Friend.objects.filter (person1 = A) объединение Friend.objects.filter (person2 = A) #unclean с необходимостью объединения двух наборов
Отдельный много-много столов
другим вариантом будет модель Friend с полем друзей, которое представляет собой поле many2many, которое связывает ровно два человека. Затем выборка соответствует одному из людей в поле друзей, а затем просто возвращает модель, где человек B может быть извлечен путем вычитания A из набора друзей. Но это было бы излишним, потому что ни у одного друга-объекта никогда не было бы связанных более двух человек.
Поиск друзей: Friendship.objects.filter (people__contains = A) # запросы к двум таблицам
Итак, что, по вашему мнению, является наиболее чистым и интуитивным решением для сохранения дружеских отношений? Есть какие-то общие шаблоны, как это сделать?