Django Admin中多对多中间表筛选显示首席研究员报错排查
Django Admin项目列表显示首席研究员的错误修复
错误原因
你定义的get_PI方法参数不符合Python类实例方法的规范:模型的实例方法第一个参数必须是self(代表当前模型实例),但你写成了obj,而Django Admin调用模型实例方法时,不会额外传递obj参数,因此触发了missing 1 required positional argument: 'obj'的错误。另外原方法的逻辑也未实现过滤首席研究员的需求。
修正步骤
- 调整
get_PI方法的参数,将obj改为self,遵循类实例方法的语法规则。 - 通过中间表
PersonRole过滤出当前项目中角色为Principal investigator的人员,再格式化显示结果。
修正后的代码
models.py中Project类的get_PI方法
class Project(models.Model): title = models.CharField(max_length=200) person = models.ManyToManyField(Person, through=PersonRole) def __str__(self): return self.title def get_PI(self): # 通过反向关联查询当前项目的首席研究员记录 pi_roles = self.personrole_set.filter(person_role="Principal investigator") # 格式化显示人员信息,多个PI用逗号分隔 return ', '.join([str(role.person) for role in pi_roles])
Admin代码无需修改
class ProjectAdmin(ImportExportModelAdmin): list_filter = [PersonFilter, FunderFilter] list_display = ("title", "get_PI") ordering = ('title',)
补充说明
self.personrole_set是Django自动生成的反向关联管理器,用于从Project实例查询关联的PersonRole记录。- 利用
filter(person_role="Principal investigator")筛选出目标角色的关联记录,再通过role.person获取对应的Person对象,最后调用Person类的__str__方法完成格式化显示。
内容的提问来源于stack exchange,提问作者HBMCS
相关产品推荐
相关产品推荐

