如何找到共享多对多关系的模型类型的所有对象?

Posted

技术标签:

【中文标题】如何找到共享多对多关系的模型类型的所有对象?【英文标题】:How can I find all objects of a model type that share a many-to-many-relationship? 【发布时间】:2020-04-12 13:58:36 【问题描述】:

所以,我有两个模型类,让我们使用 django 文档示例并将它们称为 Person 和 Group。这些以多对多的关系相关——一个人可以在多个组中,组可以有多个人。如果我有一个 Person 对象,那么找到与他们共享组的所有其他 Person 的最佳方法是什么?

编辑:这是我的代码的一种松散布局:

class Group(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Person(models.Model):
    name = models.CharField(max_length=50)
    various other fields
    groups = models.ManyToManyField(Group)

【问题讨论】:

【参考方案1】:
class Person(models.Model):
    name = models.CharField(max_length=255)
    details = models.TextField(default='', blank=True)
    status_id = models.PositiveSmallIntegerField(default=0)
    active = models.PositiveSmallIntegerField(default=1)

class Group(models.Model):
    group_name = models.CharField(max_length=255)
    persons = models.ForeignKey(
        'Person',
        on_delete=models.CASCADE,
        related_name='group_set'
    )

...

in_group_count = (
    Person.objects
    .filter(status_id__in=[2, 1], active=1)
    .annotate(order_num=Count('group_set'))
    .filter(order_num__gt=0).count()
)
not_in_group_count = (
    Person.objects
    .filter(status_id__in=[2, 1], active=1)
    .annotate(order_num=Count('group_set'))
    .filter(order_num__lte=0).count()
)
in_group_value = (
    Person.objects
    .filter(status_id__in=[2, 1], active=1)
    .annotate(order_num=Count('group_set'))
    .filter(order_num__gt=0).values()
)

【讨论】:

请详细说明。这段代码如何提供答案? 在列表 in_group_value 我们将拥有该组的所有成员 我想我应该更清楚一点,我明确地使用了 ManyToManyField,只是一个外键关系。【参考方案2】:

我不知道这两个模型中的哪一个包含 ManyToMany 字段。它在您的“组”模型中应该可以工作(“人”是您的参考人):

qs = Person.objects.filter(group__in=person.group_set.all()).exclude(id=person.pk).distinct()

为您提供共享一个组的所有 Person 对象,而无需双打。如果 m2m 字段在您的 Person 模型中,这应该可以完成工作

qs = Person.objects.filter(groups__in=person.groups.all()).exclude(id=person.pk).distinct()

【讨论】:

所以根据我添加的代码,你是说后一个例子应该适合我? 抱歉,第二个代码包含错误。修复它并使用您的模型对其进行测试。工作。

以上是关于如何找到共享多对多关系的模型类型的所有对象?的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate 在多对多关系中

如何在多对多关系 Laravel 中检索所有相关模型?

Hibernate的多对多关联关系

Django 从多对多关系中删除对象

从 Django QuerySet 中获取所有相关的多对多对象

雄辩的多对多对多 - 如何轻松加载远距离关系