Plusieurs M2M dans django
Question
J'ai deux modèles dans Django pour une carte en 2d basé sur le jeu:
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)
Maintenant, je veux juste associer ces deux modèles à l'aide d'UN tableau:
class ShopBlockAssoc(models.Model):
block = models.ForeignKey(Block)
shop = models.foreignKey(Shop)
Après j'ai mis le through
champ ShopBuilding
modèle, Django yiled plusieurs échoue lorsque syncdb, comme
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'.
Si j'ai mis db_table
champ de Django dit:
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.
Comment pourrais-je résoudre ce problème?J'ai vraiment envie de faire en sorte que ces boutique-bloc de relations en utilisant le partage d'un même intermédiaire associer modèle avec les mêmes db_table
La solution
Le problème est que sur le modèle Block
il essaie de créer en arrière des liens.Django noms de ces liens en fonction du Modèle, dans votre cas pour tous les ManyToMany il essaie de créer shopbuilding_set
et les noms d'entrer en collision.Pour éviter cela, ajoutez related_name
, par exemple:
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")
Ensuite, vous serez en mesure d'accéder à ShopBuilding
à partir de Block
exemple comme ceci:
block.shopbuilding_npc_set.all()