首页 > 解决方案 > 按多对多关系中的中间模型字段过滤

问题描述

我想在组织之间建立友谊关系。我在模型中添加了一个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

标签: pythondjangodjango-models

解决方案


我认为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)

推荐阅读