Фильтр по полю промежуточной модели в отношении «многие ко многим» - PullRequest
0 голосов
/ 06 февраля 2019

Я хочу создать дружеские отношения между организациями.Я добавил поле connected_organisations в свою модель Organisation:

class Organisation(models.Model):
    ...
    connected_organisations = models.ManyToManyField('self',
                                                     related_name='organisations_connected',
                                                     through='Connection',
                                                     through_fields=('requester', 'requestee'),
                                                     symmetrical=False,
                                                     blank=True)

Затем я создал Connection в качестве промежуточной модели:

class Connection(models.Model):
    requester = models.ForeignKey(Organisation, related_name='requester', null=True, on_delete=models.CASCADE)
    requestee = models.ForeignKey(Organisation, related_name='requestee', null=True, on_delete=models.CASCADE)
    is_connected = models.BooleanField(default=False)

Поле is_connected указывает, является лизапрос на дружбу одобрен запрашивающим или, если запрос еще не завершен.

Я создаю соединение между org1 и org2 с:

Connection.objects.create(requester=org1, requestee=org2)

Я знаю, что могу сделать:

org1.connected_organisations.all()

и это вернет org2, но я не могу найти, как я могу отфильтровать их по полю is_connected.

Я пробовал что-то вроде:

Organisation.objects.filter(connected_organisations__requestee=org2, connected_organisations__is_connected=True)

но я получаю:

django.core.exceptions.FieldError: Связанное поле получило недопустимый поиск: is_connected

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Я думаю, что related_names, который вы используете, немного вводит в заблуждение, поскольку они должны представлять обратное отношение, поэтому, возможно, измените их на что-то вроде этого (не знаю вашего точного варианта использования).Например.org.connections_requested.all() вернет набор запросов, связывающий все соединения, где org - это requester.

class Connection(models.Model):
    requester = models.ForeignKey(Organisation, related_name='connections_requested', null=True, on_delete=models.CASCADE)
    requestee = models.ForeignKey(Organisation, related_name='connections_joined', null=True, on_delete=models.CASCADE)
    is_connected = models.BooleanField(default=False)

. Вы можете отфильтровать по этим отношениям:

organisations = Organisation.objects.filter(
    connections_requested__requestee=org2, 
    connections_requested__is_connected=True
).distinct() # you may need that 

Также вы можете напрямую отфильтроватьна Connection класс:

connections = Connection.objects.filter(is_connected=True)
0 голосов
/ 06 февраля 2019

Вы можете просто напрямую использовать сквозную модель (это то, что я обычно делаю в этой ситуации):

qs = Connection.objects.filter(requester=org1, requestee=org2, is_connected=True)
...