Django связанные модели поля запросов (общие друзья) - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть модель дружбы:


class Friendship(models.Model):
    user = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="friend1", null=True, blank=True)
    other_user = models.ForeignKey(
        Account, on_delete=models.CASCADE, related_name="friend2", null=True, blank=True)
    date_created = models.DateTimeField(auto_now=True)

    objects = FriendshipManager()

    class Meta:
        verbose_name = "friendship"
        verbose_name_plural = "friendships"
        unique_together = ("user", "other_user")

    def __str__(self):
        return f'{self.user} is friends with {self.other_user}.'

и эта функция возвращает всех пользователей, которые являются общими друзьями двух учетных записей


def mutual_friends(self, account1, account2):
        mutual_friends = Account.objects.filter(
            Q(friend2__user=account1) & Q(friend2__user=account2))
        return mutual_friends

На основании моего (ограниченного) понимания того, какAPI запросов работает, я думаю, что это должно вернуть всех пользователей, которые имеют отношение "friend2" с таблицей Friendship, где пользователь "friend1" - это account1 или account2. Я все еще привыкаю к ​​запросам с django, так что, если кто-то может сообщить мне, что я делаю неправильно, это было бы здорово.

Спасибо!

1 Ответ

0 голосов
/ 07 ноября 2019

Ваш дизайн модели мне не подходит. На данный момент вы можете поместить любой экземпляр Account как user или other_user, и, поскольку они оба ссылаются на одну и ту же модель (Account), при выполнении любого извлечения из базы данных вам необходимо учитывать обаfields.

Лучшим дизайном IMO было бы использовать ManyToManyField (отношение «многие ко многим») в модели Account для себя, так как одна учетная запись может иметь несколько других учетных записей в качестве друзей и вице. наоборот. Итак:

class Account(models.Model):
    ...
    friends = models.ManyToManyField('self')
    ...

Теперь вы можете добавлять друзей, например:

account_foo.friends.add(account_bar, account_spam)

account_* Account экземпляров.

Вы можете получить всех друзейaccount_foo как:

account_foo.friends.all()

Проверьте документ «многие ко многим» для различных примеров интеграции данных и запросов.


Теперь, чтобынайдите общих друзей, например, account_foo и account_bar, вы можете сначала найти всех друзей account_foo, а затем посмотреть, кто из них также дружит с account_bar:

friends_with_foo = account_foo.friends.values_list('pk', flat=True)
mutual_friends_of_foo_bar = account_bar.friends.filter(pk__in=friends_with_foo)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...