2010-01-05 6 views
15

Tworzę grupę osób i członkostwo zgodnie z opisem w dokumentach Django dla modelu pośredniego.Pola dostępu w pośrednim modelu 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) 

Jest możliwe, aby uzyskać dostęp do obiektu osoba z grupy z:

>>>Group.members.name 

Czy Django tworzy kolejne zapytanie do sprowadzenia osoby? Czy mogę uzyskać dostęp do pola date_joined z obiektu grupy?

Rzecz, która mnie niepokoi to, że będę oczekiwać, aby uzyskać nazwę pola osoba posiadająca:

>>>Group.members.person.name 

Co się stanie, jeśli dana osoba ma pole „Nazwa”, a także pośrednią model ma pole „nazwa ".

Odpowiedz

29

Pole członków w twoim przykładzie to ManyToManyField, więc jest to sposób na dostęp do wielu osób, a nie jednej osoby. Obiekt, który jest w tej dziedzinie członków jest faktycznie specjalnym typem menedżera, a nie osoba:

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

Aby lepiej zrozumieć, co Manager jest see the documentation.

Aby uzyskać dostęp nazwisko osoby byś zrobił, na przykład:

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

Nie można uzyskać dostęp do pól w modelu członkostwa poprzez menedżera w dziedzinie członków. Aby uzyskać dostęp do wszystkich dziedzinach w nim zrobisz:

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

a więc jeśli miał pole o nazwie name w modelu członkostwa, by uzyskać dostęp to tak:

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

Drugim sposobem aby uzyskać dostęp do nazwy osoba byłaby:

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

nadzieję, że pomoże trochę :)

+0

co mówisz ma sens i pasuje jak rozumiem modeli w Django. Co mnie zdezorientowało to django docs o modelu intemedaite na http://docs.djangoproject.com/en/1.0/topics/db/models/#extra-fields-on-many-to-many-relationships Pokazują ten przykład z te same modele powyżej: # Znajdź wszystkie grupy z członkiem, którego nazwisko zaczyna się od "Paul" >>> Group.objects.filter (members__name__startswith = 'Paul') [] Spodziewałbym się ma to być: >>> Group.objects.filter (members__person__name__startswith = 'Paul') – pablo

+0

To "Group.objects.filter (members__name__startswith = 'Paul')" ponieważ członkowie są menedżerami. Musisz upewnić się, że rozumiesz, że członkowie nie są obiektem członkowskim, ale obiektem ManyRelatedManager. Myślę, że może ci pomóc, jeśli przeczytasz więcej o tym, czym są Menedżerowie. P.S.Jeśli wpiszesz „python manage.py shell” w projekcie, który ma te modele, można spróbować umieścić w „Group.objects.filter (members__person__name__startswith =«Paul»)” i zobaczyć, co się dzieje - może to pomoże? –

+0

Rozumiem, że członkowie są menedżerami i czytam o menedżerach. Nie rozumiem, w jaki sposób członkowie decydują się używać nazwy dla Osoby, a nie dla Grupy. Oba mają to pole. Jest również możliwe, że członkostwo będzie miało nazwę pola. Czy mogę to przefiltrować? – pablo

4

Użyj zarządzać R klasy członkostwa:

MyGroup.membership_set.all() 

zamiast:

MyGroup.members.all()