django中的多个M2M
我在Django有两个模型用于基于2d地图的游戏:django中的多个M2M,django,model,m2m,Django,Model,M2m,我在Django有两个模型用于基于2d地图的游戏: class Block(models.Model): type = models.IntegerField() class ShopBuilding(models.Model): house_blocks = models.ManyToManyField(Block) street_blocks = models.ManyToManyField(Block) river_blocks = models.ManyToMa
class Block(models.Model):
type = models.IntegerField()
class ShopBuilding(models.Model):
house_blocks = models.ManyToManyField(Block)
street_blocks = models.ManyToManyField(Block)
river_blocks = models.ManyToManyField(Block)
decoration_blocks = models.ManyToManyField(Block)
npc_blocks = models.ManyToManyField(Block)
现在我只想使用一个表将这两个模型关联起来:
class ShopBlockAssoc(models.Model):
block = models.ForeignKey(Block)
shop = models.foreignKey(Shop)
我在ShopBuilding
模型中设置了through
字段后,Django在syncdb时多次失败,如
Error: One or more models did not validate:
tnew.shopbuilding: Accessor for m2m field 'house_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'house_blocks'.
tnew.shopbuilding: Accessor for m2m field 'house_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'house_blocks'.
tnew.shopbuilding: Accessor for m2m field 'house_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'house_blocks'.
tnew.shopbuilding: Accessor for m2m field 'house_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'house_blocks'.
tnew.shopbuilding: Accessor for m2m field 'street_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'street_blocks'.
tnew.shopbuilding: Accessor for m2m field 'street_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'street_blocks'.
tnew.shopbuilding: Accessor for m2m field 'street_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'street_blocks'.
tnew.shopbuilding: Accessor for m2m field 'street_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'street_blocks'.
tnew.shopbuilding: Accessor for m2m field 'river_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'river_blocks'.
tnew.shopbuilding: Accessor for m2m field 'river_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'river_blocks'.
tnew.shopbuilding: Accessor for m2m field 'river_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'river_blocks'.
tnew.shopbuilding: Accessor for m2m field 'river_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'river_blocks'.
tnew.shopbuilding: Accessor for m2m field 'decoration_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'decoration_blocks'.
tnew.shopbuilding: Accessor for m2m field 'decoration_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'decoration_blocks'.
tnew.shopbuilding: Accessor for m2m field 'decoration_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'decoration_blocks'.
tnew.shopbuilding: Accessor for m2m field 'decoration_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'decoration_blocks'.
tnew.shopbuilding: Accessor for m2m field 'npc_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'npc_blocks'.
tnew.shopbuilding: Accessor for m2m field 'npc_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'npc_blocks'.
tnew.shopbuilding: Accessor for m2m field 'npc_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'npc_blocks'.
tnew.shopbuilding: Accessor for m2m field 'npc_blocks' clashes with related m2m field 'Block.shopbuilding_set'. Add a related_name argument to the definition for 'npc_blocks'.
如果我设置db_table
字段,Django会说:
The model has two manually-defined m2m relations through the model, which is not permitted. Please consider using an extra field on your intermediary model instead.
我怎样才能解决这个问题?我真的想确保那些商店区块关系使用的是共享同一中间关联模型和同一个db_表。问题是,在模型
区块上,它试图创建反向链接。Django根据模型命名这些链接,在您的案例中,它尝试创建shopbuilding\u集合,但名称冲突。要避免此情况,请添加相关的\u名称,例如:
class ShopBuilding(models.Model):
house_blocks = models.ManyToManyField(Block, related_name="shopbuilding_house_set")
street_blocks = models.ManyToManyField(Block, related_name="shopbuilding_street_set")
river_blocks = models.ManyToManyField(Block, related_name="shopbuilding_river_set")
decoration_blocks = models.ManyToManyField(Block, related_name="shopbuilding_decoration_set")
npc_blocks = models.ManyToManyField(Block, related_name="shopbuilding_npc_set")
然后,您可以从块
实例访问商店建筑
,如下所示:
block.shopbuilding\u npc\u set.all()
问题在于,在modelblock
上,它试图创建反向链接。Django根据模型命名这些链接,在您的案例中,它尝试创建shopbuilding\u集合,但名称冲突。要避免此情况,请添加相关的\u名称,例如:
class ShopBuilding(models.Model):
house_blocks = models.ManyToManyField(Block, related_name="shopbuilding_house_set")
street_blocks = models.ManyToManyField(Block, related_name="shopbuilding_street_set")
river_blocks = models.ManyToManyField(Block, related_name="shopbuilding_river_set")
decoration_blocks = models.ManyToManyField(Block, related_name="shopbuilding_decoration_set")
npc_blocks = models.ManyToManyField(Block, related_name="shopbuilding_npc_set")
然后,您可以从块
实例访问商店建筑
,如下所示:
block.shopbuilding\u npc\u set.all()
谢谢,但是如何确保这些字段使用相同的中间模型?如果您想要一个中间模型,您不需要创建5个多个关系,您只需创建一个。比如blocks=models.ManyToManyField(Block)就是这样。问题是,当您有一个中间模型时,您不能有“类型”,所以Django ORM基本上不支持一个assoc模型的多个相同m2m?您可以创建模型,添加“类型”字段,并在中指定该模型。但创建这样的对象比较困难,因为您总是需要指定“type”字段等。Django不会将许多关系合并到一个对象中。您始终可以创建一些“访问者”和管理器来帮助您处理自定义关系(DRY)。无论如何,您指定的ShopBlockAssoc
模型是标准的多人关系。基本上,这与编写blocks=models.ManyToManyField(Block)
是一样的。您可以从ShopBuilding中选择所有区块,也可以从block中选择所有商店,但您没有house、street、river等类型。是的,谢谢,但如何确保这些字段使用相同的中间模型?如果您想要一个中间模型,您不需要创建5个多个关系,您只需要创建一个。比如blocks=models.ManyToManyField(Block)就是这样。问题是,当您有一个中间模型时,您不能有“类型”,所以Django ORM基本上不支持一个assoc模型的多个相同m2m?您可以创建模型,添加“类型”字段,并在中指定该模型。但创建这样的对象比较困难,因为您总是需要指定“type”字段等。Django不会将许多关系合并到一个对象中。您始终可以创建一些“访问者”和管理器来帮助您处理自定义关系(DRY)。无论如何,您指定的ShopBlockAssoc
模型是标准的多人关系。基本上,这与编写blocks=models.ManyToManyField(Block)
是一样的。你们可以从ShopBuilding中选择所有街区,也可以从block中选择所有商店,但你们并没有像house、street、river这样的类型。