过滤模型对象,然后选择ForeignKey字段

时间:2016-10-01 09:04:03

标签: django django-models django-queryset

我在Django中有这些模型:

class Person(models.Model):
    ...

class Group(models.Model):
    ...

class Membership(models.Model):
    person = models.ForeignKey(Person, related_name='memberships')
    group = models.ForeignKey(Group, related_name='memberships')
    is_admin = models.BooleanField(default=False)

我想要一个返回管理员的Group方法,作为Person实例的列表 这是我找到的两个解决方案:

class Group(models.Model):
    ...

    @property
    def admins1(self):
        admin_ids = list(self.memberships.filter(is_admin=True).values_list('person', flat=True))
        return list(map(lambda ai: Person.objects.get(pk=ai), admin_ids))

    @property
    def admins2(self):
        admin_memberships = list(self.memberships.filter(is_admin=True))
        return list(map(lambda am: am.person, admin_memberships))

你有更好的想法,例如像values_list这样的QuerySet方法保留Person实例而不是person_ids?

1 个答案:

答案 0 :(得分:3)

这里的原则总是如果你需要Person实例,那么从Person开始。然后它变成了跟随关系的问题:

Person.objects.filter(membership__is_admin=True, membership__group=self)

另请注意,Membership是Person和Group之间多对多关系的直通表,因此如果您明确定义它,您的查询会变得更清晰:

class Person(models.Model):
    ...
    groups = models.ManyToManyField("Group", through="Membership")

现在上面的查询可以是:

Person.objects.filter(membership__is_admin=True, groups=self)