Поля доступа в промежуточной модели Django - PullRequest
18 голосов
/ 05 января 2010

Я создаю Группу лиц и Членство, как описано в Django docs для промежуточной модели.

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)

Можно получить доступ к человеку из объекта группы с помощью:

>>>Group.members.name

Создает ли Django другой запрос для извлечения Person? Могу ли я получить доступ к полю date_joined из объекта группы?

Меня смущает то, что я ожидал получить поле «Имя человека» с:

>>>Group.members.person.name

Что происходит, если у Person есть поле 'name', а у промежуточной модели есть поле 'name'.

Ответы [ 2 ]

32 голосов
/ 05 января 2010

Поле членов в вашем примере - это ManyToManyField, так что это способ получить доступ ко многим, а не к одному человеку. Объект, который находится под полем членов, на самом деле является специальным типом Manager, а не Person:

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

Чтобы лучше понять, что такое менеджер, см. Документацию .

Чтобы получить доступ к имени человека, вы должны сделать, например:

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

Вы не можете получить доступ к полям в своей модели членства через Менеджера в поле участников. Чтобы получить доступ к любому из полей в нем, вы должны сделать:

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

И поэтому, если у вас есть поле с именем name в вашей модели членства, вы получите к нему доступ следующим образом:

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

Второй способ доступа к имени человека:

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

Надеюсь, это немного поможет:)

4 голосов
/ 05 июля 2010

Используйте менеджера класса членства:

MyGroup.membership_set.all()

вместо:

MyGroup.members.all()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...