Django - как отсортировать/упорядочить несколько объектов по нескольким полям?
Я хочу отобразить музыкальный альбом на своем сайте, проблема в том, что сам альбом состоит из двух дисков, и каждый диск содержит x треков. Теперь мне интересно, как я могу отобразить это разделение на моем шаблоне Django, поскольку я хочу, чтобы это выглядело так:
Disc 1
- Title - 1
- Title - 2
- Title - 3
- Title - 4
...
Disc 2
- Title - 1
- Title - 2
- Title - 3
- Title - 4
...
Это мой взгляд:
def music_album_detail(request, pk):
music_album = get_object_or_404(MusicAlbums, pk=pk)
music_album_tracks = MusicTracks.objects.filter(album=music_album).order_by('track')
args = {
'music_album': music_album,
'music_album_tracks': music_album_tracks,
}
return render(request, 'App/music_album_detail.html', args)
В настоящее время в моем шаблоне я делаю только следующее:
{% for music_album_track in music_album_tracks %}
<td>{{ music_album_track.track }}</td>
...
Вот как выглядит моя модель:
class MusicAlbums(models.Model):
objects = RandomManager()
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.TextField(verbose_name=_("Title"), blank=False, null=True, editable=False, max_length=255)
artist = models.ForeignKey(MusicArtists, on_delete=models.CASCADE, related_name='album_artist')
cover = models.ImageField(verbose_name=_("Cover"), blank=True, null=True, upload_to=get_file_path_images)
cover_tn = models.ImageField(verbose_name=_("Cover Thumbnail"), blank=True, null=True, upload_to=get_file_path_images)
release_date = models.DateField(verbose_name=_("Release Date"), blank=True, null=True, editable=False)
genre_relation = models.ManyToManyField(through='GenreMusicAlbum', to='Genre')
total_discs = models.IntegerField(verbose_name=_("Total Discs #"), blank=True, null=True,)
total_tracks = models.IntegerField(verbose_name=_("Total Tracks #"), blank=True, null=True,)
copyright = models.TextField(verbose_name=_("Copyright"), blank=True, null=True, editable=False, max_length=255)
date_added = models.DateTimeField(auto_now_add=True, blank=True, verbose_name=_("Date Added"))
class MusicTracks(models.Model):
objects = RandomManager()
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
file = models.ForeignKey(Files, on_delete=models.CASCADE, related_name='track_file')
bitrate = models.IntegerField(verbose_name=_("Bitrate (bps)"), blank=True, null=True, editable=False)
duration = models.FloatField(verbose_name=_("Duration"), blank=True, null=True, editable=False, max_length=255)
size = models.BigIntegerField(blank=True, null=True, verbose_name=_("Size (byte)"))
title = models.TextField(verbose_name=_("Title"), blank=True, null=True, max_length=255)
artist = models.ForeignKey(MusicArtists, on_delete=models.CASCADE, related_name='track_artist')
album = models.ForeignKey(MusicAlbums, on_delete=models.CASCADE, related_name='track_album')
release_date = models.DateField(verbose_name=_("Release Date"), blank=True, null=True, editable=False)
disc = models.IntegerField(verbose_name=_("Disc #"), blank=True, null=True,)
track = models.IntegerField(verbose_name=_("Track #"), blank=True, null=True,)
date_added = models.DateTimeField(auto_now_add=True, blank=True, verbose_name=_("Date Added"))
Есть идеи, как я могу установить такое изображение в моем шаблоне?
Добрые пожелания и благодарность заранее
Вы должны использовать диск в другой модели и установить FK для этого:
class MusicAlbums(models.Model):
...
class MusicDiscs(models.Model):
album = models.ForeignKey(...)
number = models.IntegerField(...) # For example
class MusicTracks(models.Model):
disc = models.ForeignKey(...)
Таким образом, каждый альбом имеет несколько дисков, и каждый диск имеет свои треки
Теперь вы можете получить диски в вашем представлении и передать их вместе с дорожками в шаблон:
def music_album_detail(request, pk):
music_album_discs = Musicdiscs.objects.filter(...)
и в ваших шаблонах:
{% for music_disc in music_album_discs %}
<td>{{ music_disc.number }}</td>
{% for music_track in music_album_tracks %}
<td>{{ music_track.track }}</td>
Вы можете упорядочить набор вопросов сначала по disc
, а затем по track
:
MusicTracks.objects.filter(album=music_album).order_by('disc', 'track')
Это упорядочит все треки в альбоме по номеру диска, а затем по трекам на этих дисках.
EDIT:
Чтобы отобразить их по дискам, вы можете сделать примерно следующее:
def music_album_detail(request, pk):
music_album = get_object_or_404(MusicAlbums, pk=pk)
music_album_tracks_by_disc = {}
for track in MusicTracks.objects.filter(album=music_album).order_by('track'):
if track.disk in music_album_tracks_by_disc:
music_album_tracks_by_disc[track.disk].append(track)
else:
music_album_tracks_by_disc[track.disk] = [track]
context = {
'music_album': music_album,
'music_album_tracks_by_disc': music_album_tracks_by_disc,
}
return render(request, 'App/music_album_detail.html', context=context)
{% for disc, tracks in music_album_tracks_by_disc.items %}
<td>Disc {{ disc }}</td>
{% for track in tracks %}
<td>{{ track.track }}</td>
{% endfor %}
{% endfor %}