简体   繁体   English

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

[英]Filter model objects, then select a ForeignKey field

I have these models in Django: 我在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)

I want a Group method that returns the admins, as a list of Person instances. 我想要一个Group方法来返回管理员,作为Person实例的列表。
These are the two solutions I found: 这是我发现的两个解决方案:

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))

Do you have a better idea, eg a QuerySet method like values_list that keeps Person instances instead of person_ids? 你有更好的想法,例如一个QuerySet方法类似values_list ,保持人的实例,而不是person_ids?

The principle here is always that if you need Person instances, start from Person. 这里的原则始终是,如果需要Person实例,请从Person开始。 Then it becomes simply a matter of following the relationships: 然后,只需遵循以下关系即可:

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

Also note that Membership is the through table of a many-to-many relationship between Person and Group, so your queries become clearer if you explicitly define it as such: 另请注意,成员资格是“人”和“组”之间多对多关系的“通过”表,因此,如果您明确定义如下,则查询将变得更加清晰:

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

Now the above query can be: 现在上面的查询可以是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM