Лучшие модели для дружеских отношений (в Джанго) - PullRequest
8 голосов
/ 25 декабря 2011

Как лучше всего моделировать дружеские отношения между пользователями для сайта социальной сети?

Возможные состояния:

  • нет дружбы
  • 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) # запросы к двум таблицам

Итак, что, по вашему мнению, является наиболее чистым и интуитивным решением для сохранения дружеских отношений? Есть какие-то общие шаблоны, как это сделать?

Ответы [ 3 ]

1 голос
/ 21 октября 2018

Если вы не хотите повторно реализовывать все эти отношения с Дружбой, вы можете использовать следующий модуль: 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')

Он также предоставляет подписчиков, блокировщиков и связанных с ними менеджеров.

0 голосов
/ 26 декабря 2011

Я считаю, что это вариант использования расширенного отношения «многие ко многим», поддерживаемого Django: https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

Вместо того, чтобы просто хранить соединение между этими пользователями, вы можете хранить дополнительные свойства.Это должно очень хорошо спроецировать ваш проблемный домен на модель БД.Т.е. создайте свою связь, как только один из них инициирует дружбу, а затем установите дополнительные поля для хранения того, кто кого спрашивает и принял ли другой человек дружбу.

0 голосов
/ 26 декабря 2011

Для sql db я бы использовал отношения многие ко многим для этого.Но если вы думаете, что у вас будет много пользователей, вы можете рассмотреть графические базы данных, такие как flock-db, которая специально разработана для такого рода данных

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

(Сохраняйтерегулярные данные о sql db и сохраняем связи в базе данных графа) * ​​1006 *

...