2016-10-01 1 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) 

Я хочу групповой метод, который возвращает админ, как список экземпляров лица.
Эти два решения, которые я нашел:

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

У вас есть идея получше, например, метод QuerySet, такой как values_list, который хранит экземпляры 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