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