2010-07-30 4 views
39

Из документации Django ...Как мне получить доступ к свойствам таблицы «через» многих из многих из шаблона django?

Когда вы имеете дело только с простым многим-ко-многим, такие как смешивание и согласование пиццы и начинки, стандартный ManyToManyField все, что вам нужно. Однако иногда вам может потребоваться связать данные с отношением между двумя моделями.

Например, рассмотрите случай приложения, отслеживающего музыкальные группы, к которым принадлежат музыканты. Между человеком и группами, членами которых они являются, существует взаимосвязь «многие-ко-многим», поэтому вы можете использовать ManyToManyField для представления этих отношений. Тем не менее, есть много подробностей о членстве, которое вы, возможно, захотите собрать, например, о дате, когда человек присоединился к группе.

В этих ситуациях Django позволяет указать модель, которая будет использоваться для управления отношениями «многие ко многим». Затем вы можете поместить дополнительные поля в промежуточную модель. Промежуточная модель связана с ManyToManyField, используя сквозной аргумент, чтобы указать на модель, которая будет действовать как посредник. Для нашего музыканта, например, код будет выглядеть примерно так:

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) 

Теперь, когда вы создали свой ManyToManyField использовать ваш посредник модели (членство, в данном случае), вы готовы начните создавать некоторые отношения «многие ко многим». Вы можете сделать это путем создания экземпляров промежуточной модели:

ringo = Person.objects.create(name="Ringo Starr") 
paul = Person.objects.create(name="Paul McCartney") 
beatles = Group.objects.create(name="The Beatles") 

m1 = Membership(person=ringo, group=beatles, 
...  date_joined=date(1962, 8, 16), 
...  invite_reason= "Needed a new drummer.") 

m1.save() 

beatles.members.all() 
[<Person: Ringo Starr>] 

ringo.group_set.all() 
[<Group: The Beatles>] 

m2 = Membership.objects.create(person=paul, group=beatles, 
...  date_joined=date(1960, 8, 1), 
...  invite_reason= "Wanted to form a band.") 

beatles.members.all() 
[<Person: Ringo Starr>, <Person: Paul McCartney>] 

Источник: http://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

Мой вопрос, как я могу настроить мой взгляд и шаблон для доступа к этим дополнительные атрибуты. Скажем, у меня есть страница группы, и я хочу отобразить название группы, прокрутить записи членства и отобразить имена и дату_соединения.

Должен ли я передать объект группы в шаблон? Или я каким-то образом передаю объекты членства?

И как бы создать контуры for в шаблоне?

Спасибо.

+1

Я хотел бы рассмотреть укорочения выдержки из Джанго документации мало. Люди, которые, вероятно, будут реагировать, вероятно, уже знакомы с ними, и было бы легче определить фактический вопрос таким образом. – cji

ответ

32

Самый простой способ - просто передать группу в шаблон. Шаблоны способны переходить к отношениям между моделями, и на группе есть как члены, так и члены_setsetsetsetset.Так вот как я бы это сделать:

вид:

def group_details(request, group_id): 
    group = get_object_or_404(Group, pk=group_id) 
    return render_to_response('group_details.html', 
           {'group': group}) 

шаблона:

<h2>{{ group.name }}</h2> 
{% for membership in group.membership_set.all %} 
    <h3>{{ membership.person }}</h3> 
    {{ membership.date_joined }} 
{% endfor %} 
+2

Это прекрасно работает. Я пробовал итерацию через группу.membership.all. Мне нужно читать на _set. Благодаря! – Alex

+0

Но если вам нужно что-то более сложное, например, упорядочение, фильтрация и т. Д. Стандартная практика заключается в том, чтобы сделать это в представлении, а затем передать его через контекст? – CpILL

+0

Важным моментом является то, что имя класса в нижнем регистре сквозной таблицы используется «членство». – MagicLAMP

6

Я не уверен, что это только решение или нет, но передача объектов отношения к шаблону, безусловно, работает. По вашему мнению, получить QuerySet объектов Membership:

rel = Membership.objects.filter(group = your_group).select_related() 

и передать его в шаблон, где вы можете итерацию над ним с {% for %}

{% for r in rel %} 
    {{ r.person.name }} joined group {{ r.group.name }} on {{ r.date_joined }}<br /> 
{% endfor %} 

Обратите внимание, что это не должно выполнять какие-либо дополнительные запросы из-за select_related() ,

 Смежные вопросы

  • Нет связанных вопросов^_^