K
K
KOS_MOS2011-04-08 13:05:56
Python
KOS_MOS, 2011-04-08 13:05:56

Rendering a model with associated data - a newbie Django question?

There are two models - the first carries information about music albums, the second describes tracks from albums:

<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>

There is a controller that displays a list of albums:
<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>

How to display the list of tracks for each album?
The solution that immediately suggests itself is to get a list of album identifiers, select tracks from the Track model using these identifiers, and pass the list of tracks to the view.
In the view for each album, loop through the tracks and select those that have the same id_album identifier.
But judging by the amount of code - it seems to me that Django should have a more elegant solution, I quickly ran through the manual - I didn’t seem to find anything on the topic.
It would be possible to use the ManyToMany relationship - but in this structure it is not logical to use it.
Tell the experts!

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vladimir Chernyshev, 2011-04-08
@VolCh

Although not a specialist, I myself am only mastering jangu

<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 %}

Something like this, more details docs.djangoproject.com/en/1.3/topics/db/queries/#related-objects
PS to reduce calls to the database (“problem 1 + N” seems to be called) you can use in the controller
albums = Album.objects.select_related().order_by('id_album').all()[ 0:10]

PPS Your models are very original, I would describe it like this:
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)

O
Ololesha Ololoev, 2011-04-08
@alexeygrigorev

album.track_set.all()

S
savados, 2011-04-08
@savados

Use related_name
id_album = models.ForeignKey(Album, related_name="tracks")
Then you can write album.tracks.all().
But keep in mind that this will be n queries to the database, where n is the number of albums displayed, so be sure to implement caching.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question