2016-10-01 4 views
0

ich diese Modelle in Django haben:Filter Modellobjekte, dann wählen Sie ein ForeignKey Feld

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) 

ich eine Gruppe Methode wollen, dass die Admins zurückgibt, als eine Liste von Person-Instanzen.
Dies sind die beiden Lösungen, die ich gefunden:

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

Haben Sie eine bessere Idee haben, z.B. eine QuerySet-Methode wie values_list, die Person-Instanzen anstelle von person_ids hält?

Antwort

3

Das Prinzip hier ist immer, dass, wenn Sie Person-Instanzen benötigen, von Person starten. Dann wird es einfach eine Frage der nach den Beziehungen:

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

Beachten Sie auch, dass die Mitgliedschaft ist die durch Tabelle einer Viele-zu-viele-Beziehung zwischen Person und Gruppe, so werden Ihre Fragen klarer, wenn Sie explizit definieren so: Jetzt

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

die obige Abfrage sein kann:

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

Dieses Prinzip ist ein nützliches Lernen, danke. – danbal

Verwandte Themen