使用Django的ListView与DetailView时如何筛选仅展示对应作者的书籍
问题原因
你原有逻辑的错误点如下:
- DetailView 执行
get_context_data时已经拿到了当前请求对应的作者实例,存放在self.object中,不需要自己从kwargs取pk再额外查询 - 你直接调用
Book.objects.all()获取了全量书籍,判断逻辑if books.author is Author.pk不成立:books是书籍查询集没有author属性,Author.pk是模型类的属性,不是当前请求的作者实例主键。
修正后的代码
views.py 中的 AuthorView 修改
class AuthorView(DetailView): model = Author template_name = 'app/author.html' def get_context_data(self, *args, **kwargs): context = super(AuthorView, self).get_context_data(*args, **kwargs) # 方法1:利用外键反向关联直接取当前作者的所有书籍 context['books'] = self.object.book_set.all() # 方法2:显式过滤,效果和上面完全一致 # context['books'] = Book.objects.filter(author=self.object) return context
模板调用示例(app/author.html)
你可以直接遍历上下文中的books变量展示对应书籍:
<h2>{{ object.author.username }} 的所有书籍</h2> <ul> {% for book in books %} <li>{{ book.title }} - 价格:{{ book.price }}</li> {% empty %} <li>该作者暂未上传书籍</li> {% endfor %} </ul>
补充优化建议
你原有Author模型的定义有语法错误(类名后多了一个不必要的´符号),建议加上slug自动生成逻辑,避免手动维护slug的问题:
class Author(models.Model): author = models.ForeignKey(User, on_delete=models.CASCADE) slug = models.SlugField(unique=True, blank=False, null=False) def save(self, *args, **kwargs): if not self.slug: # 用关联的User用户名生成slug self.slug = slugify(self.author.username) super().save(*args, **kwargs)
内容的提问来源于stack exchange,提问作者AnonymousUser
相关产品推荐
相关产品推荐

