无法使用django在两个表之间设置postgresql外键

ykejflvf  于 2022-11-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(102)

试图找到对数据建模的最佳方法。
我有一个表口袋妖怪类型:

class PokemonTypesTest2(models.Model):
    name = models.CharField(max_length=25, unique=True)

它只有一个ID和名称,它将有18行。我希望能够将多个表与它相关,例如下面的基本口袋妖怪模型(我清除了大部分数据,更容易遵循:

class BasePokemonTest2(models.Model):
    #other data hidden #
    type1 = models.ForeignKey(PokemonTypesTest2, on_delete=models.CASCADE, default=1)
    type2 = models.ForeignKey(PokemonTypesTest2, on_delete=models.CASCADE, default=1)
    type3 = models.ForeignKey(PokemonTypesTest2, on_delete=models.CASCADE, default=1)

    weaknessResistanceImmune = models.ManyToManyField(PokemonTypesTest2, through='WeakResistImmune2')

我希望能够从基本口袋妖怪表的口袋妖怪打字到口袋妖怪。
问题是我从Django那里得到了这个错误:

ERRORS:
battlefield.BasePokemonTest2.type1: (fields.E304) Reverse accessor 'PokemonTypesTest2.basepokemontest2_set' for 'battlefield.BasePokemonTest2.type1' clashes with reverse accessor for 'battlefield.BasePokemonTest2.type2'.
        HINT: Add or change a related_name argument to the definition for 'battlefield.BasePokemonTest2.type1' or 'battlefield.BasePokemonTest2.type2'.

我看到了提示,但不明白它是什么意思?

j2datikz

j2datikz1#

使用外键时,如果您没有通过指定参数“related_name”来覆盖默认值,那么Django将使用一个由源模型名(PokemonTypesTest2)组成的名称,该名称以小写形式加上“_set”。这样您就可以访问一个管理器,该管理器返回所有与您的BasePokemonTest2示例相关的PokemonTypesTest2示例。例如:

>>> p = BasePokemonTest2.objects.get(id=1)
>>> p.pokemontypestest2_set.all()  # Returns all PokemonTypesTest2 objects related to BasePokemonTest2 instance

Django文档:“向后”跟踪关系
所以你在BasePokemonTest2模型中的type1,type2和type3赋值都试图使用“basepokemontest2_set”这个名字。当然,这是不允许的,因为每个related_name(在一个模型定义中)必须是唯一的。因此Django建议你使用related_name来解决冲突。
因此,要在上面的代码中按您的要求工作,您需要类似以下的内容:

type1 = models.ForeignKey(PokemonTypesTest2, on_delete=models.CASCADE, default=1, related_name="type1")
type2 = models.ForeignKey(PokemonTypesTest2, on_delete=models.CASCADE, default=1, related_name="type2")
type3 = models.ForeignKey(PokemonTypesTest2, on_delete=models.CASCADE, default=1, related_name="type3")

不过,我不认为这真的是你想要的吗?我怀疑你大概只是想要:

type = models.ForeignKey(PokemonTypesTest2, on_delete=models.CASCADE, default=1)

(You如果您不需要default _set名称,也可以在上面添加related_name(将其设置为您想要的任何名称)。)
然后,您可以访问所有与一个BasePokemonTest2相关的PokemonTypesTest2,如上所述。

相关问题