过滤模型对象,然后 select 一个 ForeignKey 字段
Filter model objects, then select a ForeignKey field
我在 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)
我想要一个 returns 管理员的 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?
这里的原则始终是,如果您需要 Person 实例,请从 Person 开始。然后它就变成了遵循关系的简单问题:
Person.objects.filter(membership__is_admin=True, membership__group=self)
另请注意,Membership 是 Person 和 Group 之间多对多关系的 table,因此如果您明确定义它,您的查询会变得更加清晰:
class Person(models.Model):
...
groups = models.ManyToManyField("Group", through="Membership")
现在上面的查询可以是:
Person.objects.filter(membership__is_admin=True, groups=self)
我在 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)
我想要一个 returns 管理员的 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?
这里的原则始终是,如果您需要 Person 实例,请从 Person 开始。然后它就变成了遵循关系的简单问题:
Person.objects.filter(membership__is_admin=True, membership__group=self)
另请注意,Membership 是 Person 和 Group 之间多对多关系的 table,因此如果您明确定义它,您的查询会变得更加清晰:
class Person(models.Model):
...
groups = models.ManyToManyField("Group", through="Membership")
现在上面的查询可以是:
Person.objects.filter(membership__is_admin=True, groups=self)