django如何从同一个模型中获得多个外键

时间:2015-01-29 08:49:37

标签: django model foreign-keys multiple-models

这是我的模特:

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')

我知道如何将物品添加到库存中,但现在我想装备它们。我该怎么做外键? 我希望能够装备我的库存中的武器

3 个答案:

答案 0 :(得分:5)

您需要将related_name添加到字段定义

...
weapon = models.ForeignKey(Inventory, related_name='weapons') 
shield = models.ForeignKey(Inventory, related_name='shields')
...

如果没有related_name,django会尝试在character_set模型中创建Inventory属性,但第二次会失败。

答案 1 :(得分:0)

如果您确实想要这样做,则每个FK都需要related_name,因为错误消息已经明确。但是,你不想这样做,因为没有意义。

您不希望具有Item的多对多关系以及特定的Inventory关系。你需要一个或另一个。一个角色可以拥有比单一武器和盾牌更多的库存物品吗?如果没有,那就放弃多对多;但是ForeignKeys应该直接指向Item:

class Character(models.Model):
    ...
    weapon = models.ForeignKey(Item, related_name="weapon_players")
    shield = models.ForeignKey(Item, related_name="shield_players")

否则,你应该删除两个外键,只使用多对多。您可以向Character模型添加方法或属性,以获取作为武器或盾牌的库存项目。此外,由于你没有在通过表上做任何额外的事情,你可以删除它; Django将自动提供一个。

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()

答案 2 :(得分:0)

这是一个老问题,但我想补充一些我今天学到的可能有用的东西:

https://pypi.python.org/pypi/django-composite-foreignkey http://django-composite-foreignkey.readthedocs.io/en/latest/quickstart.html

在创建多个外键之前,您必须通过在meta中添加unique_togther属性来声明复合主键。按照提供的指南,您可以在django项目中将多列声明为外键