Django - 如何通过多个字段 sort/order 多个对象?
Django - how to sort/order multiple objects by multiple fields?
我想在我的网站上展示一张音乐专辑,问题是专辑本身有两张光盘,每张光盘有 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')
这将按光盘编号对专辑中的所有曲目进行排序,然后按这些光盘中的曲目排序。
编辑:
要通过光盘显示它们,您可以这样做:
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 %}
我想在我的网站上展示一张音乐专辑,问题是专辑本身有两张光盘,每张光盘有 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')
这将按光盘编号对专辑中的所有曲目进行排序,然后按这些光盘中的曲目排序。
编辑:
要通过光盘显示它们,您可以这样做:
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 %}