我让我的数据库表包含一个字符串作为ID(和主键),而实际的字符串字段包含ID号,所以这两个字段似乎交换了,我不知道为什么。
这是一个基本的口袋妖怪API,使用Django 4.1.7,DRF 3.14和sqlite作为数据库。我的模型包括:卡、扩展和类型(火、水、虫、冰等)
Type是一个棘手的类,因为它包含引用另一个Type对象的属性:name,strong_agrest(Type),weak_agrest,resists,vulnerable_to.除了类型名称(字符串)之外,所有其他字段都应该引用另一个Type对象(因为一个口袋妖怪类型可以对其他类型强,对其他类型弱,对其他类型抵抗,对其他类型易受攻击)。
类型型号:
class Type(models.Model):
"""Pokémon type"""
name = models.CharField(max_length=100, unique=True, blank=False)
strong_against = models.ManyToManyField('self', blank=True, symmetrical=False, related_name="strong_versus")
weak_against = models.ManyToManyField('self', blank=True, symmetrical=False, related_name="weak_versus")
resists = models.ManyToManyField('self', blank=True, symmetrical=False, related_name="resists")
vulnerable = models.ManyToManyField('self', blank=True, symmetrical=False, related_name="vulnerable")
def __init__(self, name, *args, **kwargs):
super().__init__(*args, **kwargs)
self.name = name
def __str__(self):
return f"Type name: {self.name}, Strong against: {self.strong_against}, Weak against: {self.weak_against}, Resists: {self.resists}, Vulnerable to: {self.vulnerable}"
def __repr__(self):
return f"Type( ID: {self.pk}; NAME: {self.name})"
当我尝试填充数据库表“Type”时,我得到了奇怪的结果,类型名称字段实际上似乎包含主键值,ID字段包含实际名称,而实际上应该是相反的。我尝试使用Django的管理页面手动填充一个对象,也尝试使用bulk_create一次填充多个对象(),结果是一样的,我用Type.objects.all()
打印表格内容是这样打印的:
<QuerySet [Type( ID: Fire; NAME: 1)]>
此外,当尝试运行Type.objects.all().delete()
清除表记录时,我得到“ValueError:字段“id”需要一个数字,但得到的是“Fire”“(“Fire”是一个类型名称,似乎是作为id而不是实际名称插入的)。
我还尝试手动添加一个“id”字段,如下所示:
id = models.AutoField(primary_key=True)
结果相同。还尝试删除“name
“的“unique”属性,以防该属性以某种方式导致其被用作PK,但结果仍然相同。
最后,我决定注解掉除“name”以外的所有字段,刷新DB,重新创建并再次测试:
class Type(models.Model):
"""Pokémon type"""
name = models.CharField(max_length=100, blank=False)
同样的结果,所以即使模型是这样简单,它仍然给类型名赋值1,然后当我点击它查看细节时,我得到“ID为“Fire”的类型不存在。也许它被删除了?”
我做的另一个测试是将“Type”类名称更改为“PokemonType”(以防“Type”与某些语言或框架关键字冲突),但没有任何帮助。
奇怪的是,我的Expansion模型工作正常,数据正确地存储在同一个数据库中。
1条答案
按热度按时间yyyllmsg1#
好吧,经过这么多的麻烦我终于找到了罪魁祸首:这是我
__init__
方法:它导致“name”参数被赋给Django自动生成的“id”字段。
由于表中还有其他字段与同一个表具有多对多关系,因此我希望能够用只包含name字段的记录填充它,并将其他字段留空,例如:
Type(name="Fire")
,然后在表中有记录时更新它们以创建关系。我通过完全删除
__init__
解决了这个问题,当我将对象示例化为Type(name="Fire")
时,它仍然工作。