You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中按多字段排序对象并分碟展示音乐专辑曲目?

Solution for Displaying Multi-Disc Music Albums in Django Templates

Got it, let's get your multi-disc album tracks showing in the format you want. Here's a straightforward way to do it using Django's built-in template tags and a small adjustment to your view.

Step 1: Update the View to Sort Tracks by Disc First

First, we need to make sure our tracks are ordered by disc number (and then track number) so we can group them correctly in the template. Modify your view code like this:

def music_album_detail(request, pk):
    music_album = get_object_or_404(MusicAlbums, pk=pk)
    # Order by disc first, then track number to ensure proper grouping
    music_album_tracks = MusicTracks.objects.filter(album=music_album).order_by('disc', 'track')
    args = {
        'music_album': music_album,
        'music_album_tracks': music_album_tracks,
    }
    return render(request, 'App/music_album_detail.html', args)

Step 2: Use Django's regroup Tag in the Template

Now, use Django's {% regroup %} template tag to group tracks by their disc number. Then loop through each disc group to display the disc label followed by the track names separated by " - ".

Replace your existing template loop with this:

{% regroup music_album_tracks by disc as disc_groups %}

{% for disc_group in disc_groups %}
    <p>
        {# Handle cases where disc number might be null (default to 1) #}
        碟{{ disc_group.grouper|default:1 }}
        {% for track in disc_group.list %}
            {% if not forloop.first %} - {% endif %}
            {{ track.title }}
        {% endfor %}
    </p>
{% endfor %}

How This Works:

  • {% regroup ... %} takes your sorted track list and groups them by the disc field, creating a list of groups where each group has a grouper (the disc number) and a list of tracks in that disc.
  • The |default:1 filter ensures that any tracks with no disc number set will be grouped under "碟1".
  • The inner loop adds " - " before each track except the first one, giving you the exact format you want.

Example Output:

If you have 2 discs with 4 tracks each, this will render:

碟1 - 曲目名1 - 曲目名2 - 曲目名3 - 曲目名4
碟2 - 曲目名1 - 曲目名2 - 曲目名3 - 曲目名4

Alternative: Group in the View with itertools.groupby

If you prefer to handle grouping in the view instead of the template, you can use Python's itertools.groupby. Here's how:

Update your view:

from itertools import groupby
from operator import attrgetter

def music_album_detail(request, pk):
    music_album = get_object_or_404(MusicAlbums, pk=pk)
    tracks = MusicTracks.objects.filter(album=music_album).order_by('disc', 'track')
    # Group tracks by disc number
    disc_groups = []
    for disc_num, track_group in groupby(tracks, key=attrgetter('disc')):
        disc_groups.append({
            'disc_number': disc_num or 1,
            'tracks': list(track_group)
        })
    args = {
        'music_album': music_album,
        'disc_groups': disc_groups,
    }
    return render(request, 'App/music_album_detail.html', args)

Then your template becomes simpler:

{% for disc in disc_groups %}
    <p>
        碟{{ disc.disc_number }}
        {% for track in disc.tracks %}
            {% if not forloop.first %} - {% endif %}
            {{ track.title }}
        {% endfor %}
    </p>
{% endfor %}

Either approach will work—pick whichever you find more readable!

内容的提问来源于stack exchange,提问作者user16837137

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 11:47:40