【问题标题】:Django - how to sort/order multiple objects by multiple fields?Django - 如何按多个字段对多个对象进行排序/排序?
【发布时间】:2021-11-05 20:37:40
【问题描述】:

我想在我的网站上显示一张音乐专辑,问题是专辑本身有两张光盘,每张光盘都有 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"))

知道如何在我的模板中设置这样的描述吗?

【问题讨论】:

    标签: django django-views django-templates django-queryset


    【解决方案1】:

    您可以先按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 %}
    

    【讨论】:

      【解决方案2】:

      您应该在其他型号中使用光盘并为此设置 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>
      

      【讨论】:

      • 好的,我理解了你解决方案的第一部分,我也首先认为这是整个画面,但是你如何防止你显示每张光盘的所有曲目?目前我得到了每张光盘的所有曲目。但我只想拥有属于特定光盘的曲目
      猜你喜欢
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 2019-04-10
      相关资源
      最近更新 更多