如何向Django Paginator的per_page传变量以单页展示专辑所有曲目
解决方案
你的思路走入了误区:Django Paginator的per_page参数是全局统一的,无法为不同分页页面对象设置不同的分页长度,你完全不需要对Track模型做分页,直接通过外键反向关联查询当前专辑的所有曲目即可,具体修改步骤如下:
步骤1:优化模型(可选但推荐)
你当前Album模型的number_tracks字段为TextField,不仅类型不匹配数字存储,手动维护还容易出现数据不一致,建议替换为计算属性自动统计曲目数量:
class Album(models.Model): title = models.TextField(blank=False, null=False) artist = models.ForeignKey(Artist, on_delete=models.CASCADE) # 删掉原手动维护的number_tracks字段,新增计算属性 track_list = models.TextField(blank=True, null=True) artwork_file = models.ImageField(blank=True, null=True, max_length=500) @property def number_tracks(self): # 自动统计当前专辑关联的曲目数量,无需手动存储更新 return self.track_set.count() def __str__(self): return self.title
步骤2:修改视图逻辑
仅对Album模型做每页1张的分页,拿到当前页的专辑后直接拉取该专辑的所有曲目即可:
def index(request): # 仅对专辑做分页,每页展示1张专辑 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) # 拿到当前页的专辑对象(因为每页1张,直接取首个元素) current_album = page_obj_album[0] if page_obj_album.object_list else None # 获取当前专辑下的所有曲目,按曲目号排序,无需分页 album_tracks = current_album.track_set.order_by('track_number').all() if current_album else [] context = { 'current_album': current_album, 'album_tracks': album_tracks, 'page_obj_album': page_obj_album } return render(request, 'index.html', context)
步骤3:修改模板代码
直接展示当前专辑信息和所有关联曲目,切换按钮绑定专辑分页的上下页即可:
{% if current_album %} <!-- 展示专辑信息 --> <img src='{{ current_album.artwork_file.url }}' alt='{{ current_album.title }}封面' /> <h3> {{ current_album.artist }} </h3> <h3> {{ current_album.title }} </h3> <!-- 遍历展示专辑所有曲目 --> {% for track_obj in album_tracks %} <h2> {{ track_obj.title }} </h2> <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 %} <!-- 专辑切换按钮 --> <a href='{% if page_obj_album.has_previous %}?page={{ page_obj_album.previous_page_number }} {% endif %}'> <i class='fa fa-step-backward fa-2x'></i></a> <a href='{% if page_obj_album.has_next %}?page={{page_obj_album.next_page_number}} {% endif %}'><i class='fa fa-step-forward fa-2x'></i></a> {% endif %}
原逻辑问题说明
你原来的代码把所有专辑的所有曲目放在同一个QuerySet中做分页,per_page固定为1自然每次只能展示1首歌曲,通过反向关联查询的方式可以完全规避动态设置per_page的需求,无论专辑有多少首曲目都可以全部展示在同一页面。
内容的提问来源于stack exchange,提问作者alphaomega
相关产品推荐
相关产品推荐

