Django中ActorDetailView查询Cast报错:需为Person实例问题排查
解决Django演员详情页过滤Cast数据的问题
我帮你排查下问题所在——你现在的核心错误是把ActorDetailView的model设成了Cast,这完全搞反了!
问题根源
你要做的是演员(Person)的详情页,但当前View的model是Cast,所以self.object返回的是一个Cast实例,而不是你需要的Person实例。这就导致你用Cast.objects.filter(person_id=self.object)的时候,相当于把一个Cast对象传给了需要Person实例(或对应id)的过滤条件,自然就抛出了Cannot query "Cast object (1)": Must be "Person" instance的错误。
修复步骤
1. 修正DetailView的Model
把View的model改成Person,这样self.object才会是当前访问的演员实例:
class ActorDetailView(generic.DetailView): model = Person # 这里改成Person,对应演员详情页的主体 template_name = 'show/actor-detail.html'
2. 调整Cast数据的过滤逻辑
现在self.object是Person实例了,你有两种方式获取该演员的所有参演记录:
- 方式一:直接用外键字段过滤
def get_context_data(self, **kwargs): context = super(ActorDetailView, self).get_context_data(**kwargs) # 用Person实例直接过滤Cast的person字段 context['casts'] = Cast.objects.filter(person=self.object) return context
- 方式二:利用Django自动生成的反向关联(更简洁)
因为Person和Cast是一对多的外键关系,Django会自动给Person模型添加cast_set属性,直接调用all()就能拿到该演员的所有Cast记录:
def get_context_data(self, **kwargs): context = super(ActorDetailView, self).get_context_data(**kwargs) # 反向关联获取所有参演记录 context['casts'] = self.object.cast_set.all() return context
3. 修复Cast模型的get_absolute_url(可选但重要)
你当前Cast模型的get_absolute_url用的是self.id(Cast的id),但演员详情页的URL参数应该是Person的id,所以要改成:
class Cast(models.Model): # ... 其他字段不变 def get_absolute_url(self): # 用关联的person的id作为参数 return reverse('actor-detail', args=[str(self.person.id)])
验证效果
现在访问演员详情页时,self.object就是对应的Person实例,过滤出来的casts就是该演员参演的所有剧集记录,你可以在模板actor-detail.html里遍历casts,展示对应的剧集和角色信息了,和剧集详情页的逻辑就对应上了。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

