2010-01-05 15 views
15

Estoy creando un Grupo de personas y Membresía como se describe en Documentos de Django para el modelo intermedio.Campos de acceso en el modelo intermedio de 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) 

Es posible acceder a la persona de un objeto de grupo con:

>>>Group.members.name 

¿El Django crea otra consulta a buscar a la persona? ¿Puedo acceder al campo date_joined desde un objeto de grupo?

Lo que me confunde es que yo esperaría para obtener el campo de nombre de persona con:

>>>Group.members.person.name 

¿Qué pasa si una persona tiene un 'nombre' de campo y también el modelo intermedio tienen un campo de nombre ' '.

Respuesta

29

El campo de miembros en su ejemplo es ManyToManyField, por lo que es una forma de acceder a muchas personas en lugar de a una persona. El objeto que se encuentra en el campo miembros es en realidad un tipo especial de Administrador, no una persona:

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

Para comprender mejor lo que un gerente es, see the documentation.

Para acceder a nombre de una persona que lo haría por ejemplo:

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

No se puede acceder a los campos en el modelo de afiliación a través del Administrador en el campo de los miembros. Para acceder a cualquiera de los campos en que puede hacer:

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

Y así que si tenía un campo llamado nombre en su modelo de afiliación, usted podrá acceder de esta manera:

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

Una segunda forma acceder a nombre de una persona sería:

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

espero que ayude un poco :)

+0

Lo que dice tiene mucho sentido y en forma como entiendo modelos de Django. Lo que me confundió fue django docs sobre el modelo intemedaite en http://docs.djangoproject.com/en/1.0/topics/db/models/#extra-fields-on-many-to- many -relationships Muestran este ejemplo con los mismos modelos anteriores: # Encontrar todos los grupos con un miembro cuyo nombre comienza por 'Paul' >>> Group.objects.filter (members__name__startswith = 'Paul') [] Me esperaba debe ser: >>> Group.objects.filter (members__person__name__startswith = 'Paul') – pablo

+0

Es "Group.objects.filter (members__name__startswith = 'Paul')" porque los miembros son un administrador. Debe asegurarse de comprender que los miembros no son un objeto de Membresía, sino un objeto ManyRelatedManager. Creo que podría ayudarte si lees más sobre qué son exactamente los Gerentes. PDSi escribe "python manage.py shell" en un proyecto que tiene esos modelos, puede intentar poner "Group.objects.filter (members__person__name__startswith = 'Paul')" y ver qué sucede, ¿quizás eso lo ayude? –

+0

Entiendo que los miembros son un gerente y leo sobre los gerentes. No entiendo cómo los miembros deciden usar el nombre para Persona y no para Grupo. Ambos tienen este campo. También es posible que la membresía tenga un nombre de campo. Me gustaría filtrar esto? – pablo

4

uso de la gestión r de la clase de membresía:

MyGroup.membership_set.all() 

en lugar de:

MyGroup.members.all() 
Cuestiones relacionadas