Django друзья как поле «многие ко многим» — лучше хранить User или UserProfile (self) в поле?

#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 обрабатывает.