多M2M

2012-03-09 50 views
1

我有Django的两种型号的2D地图基础的游戏:多M2M

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的yiled多次失败时执行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'. 

如果我本身t 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_table

回答

3

问题是,在型号Block它试图创建向后的链接。 Django根据模型命名这些链接,对于所有ManyToMany,它试图创建shopbuilding_set并命名相互冲突。为了避免这种添加related_name,例如:

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这样的:

block.shopbuilding_npc_set.all()

+0

是感谢,但我怎么确保这些字段使用相同的中间模型? – est 2012-03-09 08:54:52

+0

如果您想要创建一个中间模型而不创建5个ManyToMany关系,则只需创建一个。像blocks = models.ManyToManyField(Block)就是这样。问题是,当你有一个中间模型时,你不能有“类型” – 2012-03-09 08:57:34

+0

所以基本上Django ORM不支持多个相同的m2m与一个assoc模型? – est 2012-03-09 09:00:58