Reputation: 137
Here is my model:
class Item(models.Model):
name = models.CharField(max_length=30)
...
choices = (
('weapon', 'weapon'),
('shield', 'shield'),
)
typeOf = models.CharField(max_length=15, choices=choices)
class Character(models.Model):
name = models.CharField(max_length=30, unique=True)
...
weapon = models.ForeignKey(Inventory) // **THIS IS WHAT I WANT TO DE BUT DOES'NT WORK**
shield = models.ForeignKey(Inventory) // **THIS IS WHAT I WANT TO DE BUT DOES'NT WORK**
inventory = models.ManyToManyField(Item, through='Inventory')
class Inventory(models.Model):
character = models.ForeignKey('Character')
item = models.ForeignKey('Item')
I know how to add item to inventory but now I want to equip them. How do I do the foreign key? I want to be able to equip weapon from my inventory
Upvotes: 4
Views: 7923
Reputation:
This is an old question but I'd like to add something I learned today that may be helpful:
https://pypi.python.org/pypi/django-composite-foreignkey http://django-composite-foreignkey.readthedocs.io/en/latest/quickstart.html
Before making multiple foreign keys you have to declare a composite primary key by adding unique_togther attribute in meta. By following the provided guide you can declare mutiple columns as foreign keys in your django projects
Upvotes: 0
Reputation: 599600
If you did want to do this, you would need a related_name
on each FK, as the error message would have made clear. However, you don't want to do this, as it makes no sense.
You don't want to have both the many-to-many relationship for Item, and the specific Inventory relationships. You need one or the other. Can a character have more inventory items than just a single weapon and shield? If not, then drop the many-to-many; but the ForeignKeys should point directly at Item:
class Character(models.Model):
...
weapon = models.ForeignKey(Item, related_name="weapon_players")
shield = models.ForeignKey(Item, related_name="shield_players")
Otherwise, you should drop the two foreign keys and just use the many-to-many. You can add methods or properties to your Character model to get the inventory item that is the weapon or shield. Also, since you're not doing anything extra on the through table, you can remove it; Django will provide one automatically.
class Character(models.Model):
...
inventory = models.ManyToManyField(Item)
@property
def shield(self):
return self.inventory.filter(typeOf='shield').first()
@property
def shield(self):
return self.inventory.filter(typeOf='weapon').first()
Upvotes: 1
Reputation: 53326
You need to add related_name
to the field definition
...
weapon = models.ForeignKey(Inventory, related_name='weapons')
shield = models.ForeignKey(Inventory, related_name='shields')
...
Without the related_name
, django will try to create character_set
attribute in Inventory
model, but it will fail for 2nd.
Upvotes: 12