如何将变量传递给 Django Paginator() 的 per_page 参数以便所有专辑曲目可以显示在一页上?
How to pass variable to Django Paginator()'s per_page parameter so all album tracks can be displayed on one page?
我正在构建一个网络应用音乐播放器,使用 Django 和 Postgres 作为数据库。
我的设置现在显示每张专辑的第一首歌曲。当点击播放按钮时,视图
改变每张专辑的第一首曲目。
我想在一个页面上显示任何给定专辑的所有曲目。
单个页面将显示这些对象:
来自专辑:album_title、艺术家、artwork_file 以及来自曲目:专辑中每首曲目 track_title 和 audio_file
为此,我需要为 Django 分页器 class 中的 self.per_page 参数提供一个整数。目前设置为 1。
曲目数量因专辑而异,因此我想将其作为整数传递给变量 (Album.number_tracks)。
问题是我无法创建一个查询集来迭代并将每次迭代传递给 self.per_page 因为
Paginator 函数一次获取所有对象,而不是逐个对象。所以我不能使用任何条件循环
喜欢:
queryset = Album.objects.all()
number_of_tracks = [a.number_tracks for a in queryset]
for num_track in number_of_tracks:
# pass album's number of tracks to Paginator(per_page=num_track)
如何在单个页面上显示任何给定专辑中的所有曲目,无论歌曲数量如何?
以下是来自models.py的相关字段:
class Album(models.Model):
title = models.TextField(blank=False, null=False)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
number_tracks = models.TextField(blank=True, null=True)
track_list = models.TextField(blank=True, null=True)
artwork_file = models.ImageField(blank=True, null=True, max_length=500)
def __str__(self):
return self.title
class Track(models.Model):
title = models.TextField(blank=False, null=False)
album = models.ForeignKey(Album, on_delete=models.CASCADE)
artist = models.TextField(blank=True, null=True)
track_number = models.TextField(blank=True, null=True)
audio_file = models.FileField(blank=True, null=True, max_length=500)
def __str__(self):
return self.title
views.py
def index(request):
paginator_track = Paginator(Track.objects.order_by('album', 'track_number').all(), 1)
page_number = request.GET.get('page')
page_obj_track = paginator_track.get_page(page_number)
paginator_album = Paginator(Album.objects.order_by('artist', 'title').all(), 1)
page_number = request.GET.get('page')
page_obj_album = paginator_album.get_page(page_number)
context = {'page_obj_album': page_obj_album, 'page_obj_track': page_obj_track}
return render(request, 'index.html', context)
而在 index.html 中,我这样显示对象:
{% for album_obj in page_obj_album %}
<img src='{{ album_obj.artwork_file.url }}' alt='{{ album_obj.artwork_link }}' />
<h3> {{ album_obj.artist }} </h3>
<h3> {{ album_obj.title }} </h3>
{% endfor %}
{% for track_obj in page_obj_track %}
<h1> {{ track_obj.title }} </h1>
<a href='{% if page_obj_track.has_previous %}?page={{
page_obj_track.previous_page_number }} {% endif %}'>
<i class='fa fa-step-backward fa-2x'></i></a>
<a href='{% if page_obj_track.has_next %}?page={{page_obj_track.next_page_number}} {% endif %}'><i class='fa fa-step-forward fa-2x'></i></a>
<audio class='fc-media'>
<source src='{% if track_obj.audio_file %} {{ track_obj.audio_file.url }}
{% else %} {{ track_obj.audio_link }} {% endif %}'
type='audio/mp3'/></audio>
{% endfor %}
以防万一这对将来的任何人都有帮助——我最终重构了我的代码以使其正常工作。我没有使用内置的分页器功能,而是使用了 DetailView。以下是代码的相关部分:
我向 models.py 添加了一个 slug 字段来创建 URL:
slug = AutoSlugField(null=True, default=None, unique=True, max_length=500, populate_from='title')
views.py:
from django.views.generic.detail import DetailView
from datasource.models import Album, Track
class AlbumDetailView(DetailView):
model = Album
template_name = 'album_view.html'
def get_context_data(self, **kwargs):
context = super(AlbumDetailView, self).get_context_data(**kwargs)
context['next_album'] = Album.objects.filter(title__gt=self.object.title).order_by('title').first()
context['prev_album'] = Album.objects.filter(title__lt=self.object.title).order_by('-title').first()
context['track'] = Track.objects.filter(album=self.object).order_by('track_number')
return context
在 HTML 模板中,视图呈现如下:
{% if prev_album %}
<a href='{% url "album_detail" slug=prev_album.slug %}'><i class='fa fa-step-backward fa-2x'></i></a>
{% endif %}
{% if next_album %}
<a href='{% url "album_detail" slug=next_album.slug %}'><i class='fa fa-step-forward fa-2x'></i></a>
{% endif %}
{% for t in track %}
<h1> {{ t.title }} </h1>
<audio class='fc-media' style='width: 100%;'>
<source src='{% if t.audio_file %} {{ t.audio_file.url }} {% else %} {{ t.audio_link }} {% endif %}'type='audio/mp3'/></audio>
{% endfor %}
我正在构建一个网络应用音乐播放器,使用 Django 和 Postgres 作为数据库。
我的设置现在显示每张专辑的第一首歌曲。当点击播放按钮时,视图 改变每张专辑的第一首曲目。
我想在一个页面上显示任何给定专辑的所有曲目。
单个页面将显示这些对象:
来自专辑:album_title、艺术家、artwork_file 以及来自曲目:专辑中每首曲目 track_title 和 audio_file
为此,我需要为 Django 分页器 class 中的 self.per_page 参数提供一个整数。目前设置为 1。
曲目数量因专辑而异,因此我想将其作为整数传递给变量 (Album.number_tracks)。 问题是我无法创建一个查询集来迭代并将每次迭代传递给 self.per_page 因为 Paginator 函数一次获取所有对象,而不是逐个对象。所以我不能使用任何条件循环 喜欢:
queryset = Album.objects.all()
number_of_tracks = [a.number_tracks for a in queryset]
for num_track in number_of_tracks:
# pass album's number of tracks to Paginator(per_page=num_track)
如何在单个页面上显示任何给定专辑中的所有曲目,无论歌曲数量如何?
以下是来自models.py的相关字段:
class Album(models.Model):
title = models.TextField(blank=False, null=False)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
number_tracks = models.TextField(blank=True, null=True)
track_list = models.TextField(blank=True, null=True)
artwork_file = models.ImageField(blank=True, null=True, max_length=500)
def __str__(self):
return self.title
class Track(models.Model):
title = models.TextField(blank=False, null=False)
album = models.ForeignKey(Album, on_delete=models.CASCADE)
artist = models.TextField(blank=True, null=True)
track_number = models.TextField(blank=True, null=True)
audio_file = models.FileField(blank=True, null=True, max_length=500)
def __str__(self):
return self.title
views.py
def index(request):
paginator_track = Paginator(Track.objects.order_by('album', 'track_number').all(), 1)
page_number = request.GET.get('page')
page_obj_track = paginator_track.get_page(page_number)
paginator_album = Paginator(Album.objects.order_by('artist', 'title').all(), 1)
page_number = request.GET.get('page')
page_obj_album = paginator_album.get_page(page_number)
context = {'page_obj_album': page_obj_album, 'page_obj_track': page_obj_track}
return render(request, 'index.html', context)
而在 index.html 中,我这样显示对象:
{% for album_obj in page_obj_album %}
<img src='{{ album_obj.artwork_file.url }}' alt='{{ album_obj.artwork_link }}' />
<h3> {{ album_obj.artist }} </h3>
<h3> {{ album_obj.title }} </h3>
{% endfor %}
{% for track_obj in page_obj_track %}
<h1> {{ track_obj.title }} </h1>
<a href='{% if page_obj_track.has_previous %}?page={{
page_obj_track.previous_page_number }} {% endif %}'>
<i class='fa fa-step-backward fa-2x'></i></a>
<a href='{% if page_obj_track.has_next %}?page={{page_obj_track.next_page_number}} {% endif %}'><i class='fa fa-step-forward fa-2x'></i></a>
<audio class='fc-media'>
<source src='{% if track_obj.audio_file %} {{ track_obj.audio_file.url }}
{% else %} {{ track_obj.audio_link }} {% endif %}'
type='audio/mp3'/></audio>
{% endfor %}
以防万一这对将来的任何人都有帮助——我最终重构了我的代码以使其正常工作。我没有使用内置的分页器功能,而是使用了 DetailView。以下是代码的相关部分:
我向 models.py 添加了一个 slug 字段来创建 URL:
slug = AutoSlugField(null=True, default=None, unique=True, max_length=500, populate_from='title')
views.py:
from django.views.generic.detail import DetailView
from datasource.models import Album, Track
class AlbumDetailView(DetailView):
model = Album
template_name = 'album_view.html'
def get_context_data(self, **kwargs):
context = super(AlbumDetailView, self).get_context_data(**kwargs)
context['next_album'] = Album.objects.filter(title__gt=self.object.title).order_by('title').first()
context['prev_album'] = Album.objects.filter(title__lt=self.object.title).order_by('-title').first()
context['track'] = Track.objects.filter(album=self.object).order_by('track_number')
return context
在 HTML 模板中,视图呈现如下:
{% if prev_album %}
<a href='{% url "album_detail" slug=prev_album.slug %}'><i class='fa fa-step-backward fa-2x'></i></a>
{% endif %}
{% if next_album %}
<a href='{% url "album_detail" slug=next_album.slug %}'><i class='fa fa-step-forward fa-2x'></i></a>
{% endif %}
{% for t in track %}
<h1> {{ t.title }} </h1>
<audio class='fc-media' style='width: 100%;'>
<source src='{% if t.audio_file %} {{ t.audio_file.url }} {% else %} {{ t.audio_link }} {% endif %}'type='audio/mp3'/></audio>
{% endfor %}