2016-10-01 80 views
0

我有这些模型:筛选模型对象,然后在Django选择一个ForeignKey场

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) 

我想返回的管理员,因为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?

回答

3

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

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

另外请注意,会员是个人与集团之间的许多一对多的关系,通过表,所以你的查询变得更加清晰,如果你明确地把它定义为例如:

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

现在,上面的查询可以是:

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

这个原则是一个有用的学习,谢谢。 – danbal