在Django Admin中处理关联模型对象创建时遇外键类型错误求助
你遇到的TypeError: int() argument must be a string, a bytes-like object or a number, not 'Testcases'报错,根源出在Executedtests模型的__str__方法里,我来一步步帮你理清问题并解决:
问题原因
当你在Django里定义testcase_id = models.ForeignKey("testcases", models.CASCADE)时,这个字段对应的模型属性self.testcase_id已经是关联的Testcases实例对象,而不是数据库里存储的纯数字ID。
你在__str__里写的Testcases.objects.get(pk=self.testcase_id),相当于把一个Testcases对象传给了pk参数——但pk需要的是整数或字符串类型的ID值,这就导致了类型不匹配的错误。
解决方案
方案1:快速修正__str__方法
不需要再去数据库查询关联对象,直接用已经存在的关联实例就行,因为你已经给Testcases和Testruns定义了__str__方法,它们会自动返回易读的名称:
class Executedtests(models.Model): testcase_id = models.ForeignKey("testcases", models.CASCADE) testrun_id = models.ForeignKey("testruns", models.CASCADE) teststart = models.TimeField(blank=True, null=True) testend = models.TimeField(blank=True, null=True) def __str__(self): # 直接使用关联实例,它们的__str__会返回你定义的友好名称 return f"{self.testcase_id}, {self.testrun_id}, Start: {self.teststart}, End: {self.testend}"
方案2:规范ForeignKey字段命名(推荐)
Django的ForeignKey字段建议不要加_id后缀,因为Django会自动在数据库中生成以_id结尾的列名,模型属性直接用关联模型的单数名称更清晰,能从根源上避免混淆实例和ID的问题:
# 修正模型字段命名 class Executedtests(models.Model): # 字段名改为testcase,数据库列会自动生成testcase_id testcase = models.ForeignKey("Testcases", on_delete=models.CASCADE) testrun = models.ForeignKey("Testruns", on_delete=models.CASCADE) teststart = models.TimeField(blank=True, null=True) testend = models.TimeField(blank=True, null=True) def __str__(self): return f"{self.testcase}, {self.testrun}, Start: {self.teststart}, End: {self.testend}"
这样修改后,Admin面板的表单字段名也会更直观,以后维护代码时也不容易再犯类似的错误。
另外补充一句:你看到的Admin表单里<option value="1">Testcase: Test1</option>是完全正常的,Django会自动处理前台提交的ID值到后台模型实例的转换,问题完全出在__str__方法的错误逻辑上,修正后就能正常创建Executedtests对象了。
内容的提问来源于stack exchange,提问作者Artur Korobeynyk

