Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django中的多个M2M_Django_Model_M2m - Fatal编程技术网

django中的多个M2M

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

我在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.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()

问题在于,在model
block
上,它试图创建反向链接。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这样的类型。