#django #many-to-many #user-profile
#джанго #многие-ко-многим #профиль пользователя
Вопрос:
Я нашел два способа реализации симметричной системы дружбы (ты мой друг, поэтому я тоже твой друг) в Django:
Как предложено в документах:
class UserProfile(models.Model):
friends = models.ManyToManyField(User, related_name='friends')
Теперь я хотел бы получить все «дружественные» модели user И userprofile с одним select_related-запросом, подобным so (это должен быть обратный объединенный поиск):
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, выглядит так:
profiles = this_user.get_profile().friends.all().select_related()
Мне всегда нужны оба, пользовательский объект и связанный с ним профиль: второй подход намного проще в отношении обратного поиска с помощью select_related() , но делает практически то же самое. Однако, используя «self» в качестве ссылки на поле, Django обрабатывает для меня симметричную дружбу. Таким образом, мне не нужно вручную создавать две записи для каждого друга в базе данных. Джанго делает это за меня. Однако симметричный вариант работает только с полями, ссылающимися на «себя».
Какое решение лучше? Я ничего не могу найти по этому поводу. Любые идеи оценены по достоинству — спасибо!
Ответ №1:
Саймон,
Иногда лучше использовать существующий плагин, а не пытаться заново изобрести колесо.
Вы смотрели на django-friends?
Комментарии:
1. Хм, да, я знаю это, спасибо; также django-simple-friends ( ссылка ), однако для реализации этой функции не так много работы, и я скорее точно знаю, что происходит. Оба пакета довольно обширны по функциям, и документация о том, как их использовать, очень тонкая. Также оба приложения создают дополнительные модели — в пользу простоты я предпочитаю использовать одно поле «многие ко многим», а остальное пусть Django обрабатывает.