Я нашел два способа реализации системы симметричной дружбы (ты мой друг, поэтому я также твой друг) в Django:
Как предлагается в документах:
class UserProfile(models.Model):
friends = models.ManyToManyField(User, related_name='friends')
Теперь я хотел бы получить все «дружественные» модели пользователей и профилей пользователей с одним запросом select_related-query, например (это должен быть поиск с обратным соединением):
profiles = UserProfile.objects.filter(user__in=request.user.get_profile().friends.all()).select_related()
Я запрашиваю профиль пользователя, потому что таким образом я могу использовать select_related(), и все связанные объекты кэшируются.
С другой стороны, я могу определить свою модель, ссылаясь на поле друзей на «себя», например:
class UserProfile(models.Model):
friends = models.ManyToManyField('self')
Теперь мой поиск друзей по select_related выглядит так:
profiles = this_user.get_profile().friends.all().select_related()
Мне всегда нужны и пользовательский объект, и связанный с ним профиль: второй подход намного проще в отношении обратного поиска с помощью select_related(), но делает практически то же самое. Однако, используя «я» в качестве ссылки на поле, Джанго обрабатывает для меня симметричную дружбу. Таким образом, мне не нужно вручную создавать две записи на дружбу в базе данных. Джанго делает это за меня. Однако симметричный вариант работает только с полями, ссылающимися на себя.
Какое решение лучше? Я ничего не могу найти об этом. Любые идеи оценены - спасибо!