DjangoRest框架模型在sqlite中为主键分配一个str,为str字段分配一个数字

du7egjpx  于 2023-03-09  发布在  Go
关注(0)|答案(1)|浏览(79)

我让我的数据库表包含一个字符串作为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模型工作正常,数据正确地存储在同一个数据库中。

yyyllmsg

yyyllmsg1#

好吧,经过这么多的麻烦我终于找到了罪魁祸首:这是我__init__方法:

def __init__(self, name, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.name = name

它导致“name”参数被赋给Django自动生成的“id”字段。
由于表中还有其他字段与同一个表具有多对多关系,因此我希望能够用只包含name字段的记录填充它,并将其他字段留空,例如:Type(name="Fire"),然后在表中有记录时更新它们以创建关系。
我通过完全删除__init__解决了这个问题,当我将对象示例化为Type(name="Fire")时,它仍然工作。

相关问题