Frage
Ich habe zwei Modelle in Django für ein 2D-Kartenspiel:
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)
Jetzt möchte ich nur noch diese beiden Modelle mithilfe EINER Tabelle verknüpfen:
class ShopBlockAssoc(models.Model):
block = models.ForeignKey(Block)
shop = models.foreignKey(Shop)
Nachdem ich das eingestellt habe through
Feld hinein ShopBuilding
Modell, Django hat beim syncdb mehrere Fehler gemeldet, z
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'.
Wenn ich setze db_table
Feld Django sagt:
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.
Wie könnte ich das beheben?Ich möchte wirklich sicherstellen, dass diese Shop-Block-Beziehungen dasselbe Zwischen-Associate-Modell mit derselben db_table verwenden
Lösung
Das Problem liegt am Modell Block
es versucht, Rückwärtslinks zu erstellen.Django benennt diese Links basierend auf dem Modell, in Ihrem Fall für alle ManyToMany, die es zu erstellen versucht shopbuilding_set
und Namen kollidieren.Um dies zu vermeiden, fügen Sie hinzu related_name
, Zum Beispiel:
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")
Dann können Sie darauf zugreifen ShopBuilding
aus Block
Beispiel wie folgt:
block.shopbuilding_npc_set.all()