Рендер модели со связанными данными — вопрос по Django от новичка?

Есть две модели — первая несет информацию о музыкальных альбомах, вторая описывает треки с альбомов:
<font color="black"><a href="http://s-c.me/19881/s">Copy Source</a> | <a href="http://s-c.me/19881/h">Copy HTML</a><ol>
<li><font color="#0000ff">class</font> <font color="#cc6633">Album</font>(models.Model):</li>
<li>    id_album = models.AutoField(primary_key=True)</li>
<li>    artist = models.CharField(max_length=<font color="#008000">100</font>, null=True)</li>
<li>    disc = models.CharField(max_length=<font color="#008000">100</font>, null=True)</li>
<li> </li>
<li><font color="#0000ff">class</font> <font color="#cc6633">Track</font>(models.Model):</li>
<li>    id_track = models.AutoField(primary_key=True)</li>
<li>    id_album = models.ForeignKey(<font color="#cc6633">Album</font>)</li>
<li>    title = models.CharField(max_length=<font color="#008000">100</font>) </li>
</ol></font>



Есть контроллер который выводит список альбомов:
<font color="black"><a href="http://s-c.me/19882/s">Copy Source</a> | <a href="http://s-c.me/19882/h">Copy HTML</a><ol>
<li><font color="#0000ff">def</font> <font color="#cc6633">albums</font>(request):</li>
<li>    <font color="#cc6633">albums</font> = Album.objects.order_by(<font color="#008000">'id_album'</font>).<b>all</b>()[<font color="#008000"> 0</font>:<font color="#008000">10</font>]</li>
<li>    <font color="#0000ff">return</font> render_to_response(<font color="#008000">'albums.html'</font>, {<font color="#008000">'albums'</font>: <font color="#cc6633">albums</font>}) </li>
</ol></font>



Как для каждого альбома вывести список треков для него?


Решение которое напрашивается сразу — получить список идентификаторов альбомов, по этим идентификаторам выбрать треки из модели Track, передать во вьюху список треков.

Во вьюхе для каждого альбома делать цикл по трекам и выбирать те, у которых совпадают идентификатора id_album.


Но судя по количеству кода — мне кажется что в Django должно быть решение более элегантное, быстренько пробежался по мануалу — вроде ничего по теме не нашел.


Можно было бы использовать связь ManyToMany — но в данной структуре ее использовать не логично.


Подскажите спецы!
  • Вопрос задан
  • 2872 просмотра
Пригласить эксперта
Ответы на вопрос 3
Хоть и не спец, сам джангу только осваиваю
<ul>
{% for album in albums %}
  <li>{{ album.artist }} - {{album.disc}}
    <ol>
    {% for track in album.track_set.all %}
      <li>{{ track.title }}</li>
    {% endfor %}
    </ol>
  </li>
{% endfor %}


Как-то так, подробнее docs.djangoproject.com/en/1.3/topics/db/queries/#related-objects

P.S. для уменьшения обращений к БД («проблема 1+N» кажется называется)можно в контроллере использовать
albums = Album.objects.select_related().order_by('id_album').all()[ 0:10]


P.P.S. Модели у вас очень оригинальные, я бы так описал:
class Album(models.Model):
    artist = models.CharField(max_length=100, null=True)
    disc = models.CharField(max_length=100, null=True)
 
class Track(models.Model):
    album = models.ForeignKey(Album)
    title = models.CharField(max_length=100)
Ответ написан
alexeygrigorev
@alexeygrigorev
Переворачиватель пингвинов
album.track_set.all()
Ответ написан
Комментировать
savados
@savados
Используйте related_name

id_album = models.ForeignKey(Album, related_name="tracks")

Тогда сможете писать album.tracks.all().

Но имейте в виду, что это будет n запросов к базе, где n — количество выводимых альбомов, так что обязательно реализуйте кеширование.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы