2010-01-05 13 views
15

Ich erstelle eine Personengruppe und Mitgliedschaft wie in Django Docs für Zwischenmodell beschrieben.Zugriff Felder in Django Zwischenmodell

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) 

Es ist möglich, die Person aus einer Gruppe Objekt zuzugreifen mit:

>>>Group.members.name 

Does Django erzeugt eine weitere Abfrage, um die Person zu holen? Kann ich über ein Gruppenobjekt auf das Feld date_joined zugreifen?

Was ich verwirrt bin, dass ich mit der Person Namensfeld zu erhalten erwarten würde:

>>>Group.members.person.name 

Was passiert, wenn eine Person ein Feld ‚Namen‘ hat und auch das Zwischenmodell ein Feld ‚Namen haben ".

Antwort

29

Das Mitgliederfeld in Ihrem Beispiel ist ein ManyToManyField. Es ist also eine Möglichkeit, auf viele Personen statt auf eine Person zuzugreifen. Das Objekt, das unter dem Mitglied Bereich ist eigentlich eine spezielle Art von Manager nicht einer Person:

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

Um besser zu verstehen, was ein Manager ist, see the documentation.

Um den Namen einer Person gelangen Sie zum Beispiel tun würde:

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

Sie die Felder in Ihrer Mitgliedschaft Modell nicht zugreifen können, über die Manager der Mitglieder Feld. Um eines der Felder in darauf zugreifen würden Sie tun:

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

Und so, wenn Sie ein Feld hatte genannt Namen in Ihrem Membership-Modell, würden Sie es wie folgt zugreifen:

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

Ein zweiter Weg für den Zugriff auf Namen wäre eine Person:

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

Hoffnung, die ein wenig :)

+0

Was Sie sagen, ist absolut sinnvoll und passen, wie ich Modelle in django verstehen. Was mich verwirrte, war django docs über das Modell von intermedaite unter http://docs.djangoproject.com/en/1.0/topics/db/models/#extra-fields-on-many-to-many-relationships Sie zeigen dieses Beispiel mit die gleichen Modelle oben: # Finden Sie alle Gruppen mit einem Mitglied, dessen Name mit 'Paul' beginnt >>> Group.objects.filter (members__name__startswith = 'Paul') [] Ich würde erwarten es zu sein: >>> Group.objects.filter (members__person__name__startswith = 'Paul') – pablo

+0

Es ist "Group.objects.filter (members__name__startswith = 'Paul')" weil Mitglieder ein Manager ist. Sie müssen sicherstellen, dass Sie verstehen, dass Member kein Mitgliedschaftsobjekt, sondern ein ManyRelatedManager-Objekt ist. Ich denke, es könnte Ihnen helfen, wenn Sie mehr darüber lesen, was Manager genau sind. P.S.Wenn Sie in einem Projekt mit diesen Modellen "python manage.py shell" eingeben, können Sie versuchen, "Group.objects.filter (members__person__name__startswith = 'Paul')" einzufügen und zu sehen, was passiert - vielleicht hilft Ihnen das? –

+0

Ich verstehe, dass Mitglieder ein Manager ist und ich über Manager gelesen habe. Ich verstehe nicht, wie Mitglieder beschließen, den Namen für Person und nicht für Gruppe zu verwenden. Beide haben dieses Feld. Es ist auch möglich, dass die Mitgliedschaft einen Feldnamen hat. Ich würde das filtern? – pablo

4

Verwendung hilft die Verwaltung r der Zugehörigkeitsklasse:

MyGroup.membership_set.all() 

statt:

MyGroup.members.all() 
Verwandte Themen