Django queryset с двунаправленными отношениями - PullRequest
0 голосов
/ 16 января 2020

Я пытаюсь создать эффективный набор запросов со следующей моделью:

class Connection(models.Model):
    from = models.ForeignKey(User, related_name='from_connections')
    to = models.ForeignKey(User, related_name='to_connections')
    status = models.SmallIntegerField()

Я пытаюсь для указанного пользователя получить список всех его соединений (так что он либо from, либо to) и комментирует статус, в котором он находится from, но также комментирует обратный статус, в котором он to.

. Например,

from |   to   |   status
------------------------
   A |      B |        1
   B |      A |        0
   C |      A |        2
   A |      D |        2

результаты будут примерно такими:

user |      status | reverse_status
-----------------------------------
   B |           1 |              0
   C |        None |              2
   D |           2 |           None

Самое близкое решение, которое я получил до сих пор, выглядит примерно так:

qs = Connection.objects.filter(from_id=a_id)

reverse_qs = Connection.objects.filter(from_id=OuterRef("to_id"), to_id=a_id)
qs = qs.annotate(reverse_status=Subquery(reverse_status.values("status")[:1]))

Это почти дает мне то, что Мне нужно, но так как набор запросов включает только результаты, где пользователь A равен from, результаты, очевидно, ничего не содержат для пользователя C (из приведенной выше таблицы примеров).

Я также попытался изучить маршрут с использованием связанных имен, таких как

User.objects.filter(Q(from_connections__to=a_id)|Q(to_connections__from=a_id).annotate...

, но этот подход не дал мне много.

У кого-нибудь есть идеи, как решить эту проблему с помощью Django ORM? Очень ценится.

1 Ответ

0 голосов
/ 17 января 2020

Когда вы создаете модель, имеющую 2 ForeignKey с, вы должны указать related_name, пример:

class Connection(models.Model):
    from = models.ForeignKey(User, related_name = 'from_connection')
    to = models.ForeignKey(User, related_name = 'to_connection')
    status = models.SmallIntegerField()

, которая поможет в обратных отношениях, более подробная информация в документах

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...