Django开发歌曲网站访问作者页触发MultipleObjectsReturned错误如何解决
错误原因
报错由两个逻辑问题共同导致:
- 你在
AuthorSongListView的get_queryset方法中错误使用了get_object_or_404查询Songs对象:get_object_or_404底层调用模型的get()方法,要求查询结果必须且仅存在1条匹配数据。而你的业务场景中同一个作者对应多首歌曲,传入Ed Sheeran作为参数查询时返回了2条匹配的歌曲数据,因此触发MultipleObjectsReturned报错。 - 就算
get_object_or_404没有报错,后续Songs.objects.filter(author=author)的逻辑也不成立:此时author变量是Songs模型实例,而Songs表的author字段是字符串类型,字段类型不匹配,无法正确过滤数据。
修复方案
直接修改views.py中AuthorSongListView的get_queryset方法即可,无需先查询单个Songs对象,直接用URL传递的作者名过滤所有歌曲:
首先在views.py开头导入Http404:
from django.http import Http404
修改类视图的对应方法:
class AuthorSongListView(ListView): model = Songs template_name = 'author_songs.html' context_object_name = 'songs' paginate_by = 2 def get_queryset(self): # 直接从URL参数取作者名字符串 author_name = self.kwargs.get('author') # 过滤该作者的所有歌曲 songs_queryset = Songs.objects.filter(author=author_name) # 如果该作者没有相关歌曲,返回404 if not songs_queryset.exists(): raise Http404(f"未找到作者 {author_name} 的相关歌曲") return songs_queryset
可选优化建议
当前你把作者名以CharField形式存在Songs表中,容易出现重复、拼写不一致等脏数据问题,后续可以拆分出独立的Author模型,通过外键和Songs表关联,数据结构会更合理。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

