2010-01-05 16 views
15

Sto creando un gruppo di persone e un'iscrizione come descritto in Documenti Django per il modello intermedio.Campi di accesso nel modello intermedio Django

class Person(models.Model): 
    name = models.CharField(max_length=128) 

    def __unicode__(self): 
    return self.name 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership') 

    def __unicode__(self): 
    return self.name 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

E 'possibile accedere alla persona da un oggetto di gruppo con:

>>>Group.members.name 

fa Django crea un'altra query per andare a prendere la persona? Posso accedere al campo date_joined da un oggetto Gruppo?

La cosa che confonde me è che mi aspetto di ottenere il campo del nome Persona con:

>>>Group.members.person.name 

Cosa succede se una persona ha un campo 'nome' e anche il modello intermedio hanno un campo 'nome '.

risposta

29

Il campo membri nell'esempio è ManyToManyField, quindi è un modo per accedere a più persone anziché a una persona. L'oggetto che si trova sotto il campo membri è in realtà un tipo speciale di Manager, non è una Persona:

>>>print my_group.members 
<django.db.models.fields.related.ManyRelatedManager object at 0x181f7d0> 

per capire meglio cosa un manager è, see the documentation.

Per accedere il nome di una persona con cui vorresti fare per esempio:

>>>for person in my_group.members.all(): 
>>> print person.name 

Non è possibile accedere ai campi nel modello di iscrizione tramite il Gestore nel campo membri. Per accedere a uno dei campi in esso si dovrebbe fare:

>>>for membership in my_group.membership_set.all(): 
>>> print membership.date_joined 

E così, se si ha un campo denominato nome nel modello di iscrizione, si dovrebbe accedere in questo modo:

>>>for membership in my_group.membership_set.all(): 
>>> print membership.name 

Un secondo modo per accedere nome di una persona potrebbe essere:

>>>for membership in my_group.membership_set.all(): 
>>> print membership.person.name 

Speranza che aiuta un po ':)

+0

Quello che stai dicendo senso perfetto e in forma come capisco modelli in Django. Ciò che mi ha confuso era django docs sul modello intemedaite su http://docs.djopoproject.com/en/1.0/topics/db/models/#extra-fields-on-many-to-many-relationships Mostrano questo esempio con gli stessi modelli sopra: # Trova tutti i gruppi con un membro il cui nome inizia con 'Paul' >>> Group.objects.filter (members__name__startswith = 'Paul') [] Mi aspetterei deve essere: >>> Group.objects.filter (members__person__name__startswith = 'Paul') – pablo

+0

È "Group.objects.filter (members__name__startswith = 'Paul')" perché i membri sono Manager. Devi assicurarti di capire che i membri non sono un oggetto Membership, ma un oggetto ManyRelatedManager. Penso che potrebbe aiutarti se leggi di più su cosa sono esattamente i Manager. Post scriptumSe digiti "python manage.py shell" in un progetto che ha quei modelli, puoi provare a inserire "Group.objects.filter (members__person__name__startswith = 'Paul')" e vedere cosa succede - forse questo ti aiuterà? –

+0

Capisco che i membri sono un manager e ho letto dei gestori. Non capisco come i membri decidano di utilizzare il nome per Persona e non per Gruppo. Entrambi hanno questo campo. È anche possibile che l'appartenenza abbia un nome di campo. Vorrei filtrare questo? – pablo

4

Utilizzare la gestione r della classe di appartenenza:

MyGroup.membership_set.all() 

invece di:

MyGroup.members.all() 
Problemi correlati