简体   繁体   English

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

[英]django how to have multiple foreignkey from the same model

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我希望能够从我的库存中装备武器

You need to add related_name to the field definition您需要将related_name添加到字段定义中

...
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.如果没有related_name ,django 将尝试在Inventory模型中创建character_set属性,但第二次会失败。

If you did want to do this, you would need a related_name on each FK, as the error message would have made clear.如果你确实想做到这一点,你需要一个related_name每个FK,作为错误信息就会明确。 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.您不想同时拥有 Item 的多对多关系和特定的 Inventory 关系。 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:但是 ForeignKeys 应该直接指向 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.您可以向 Character 模型添加方法或属性以获取作为武器或盾牌的库存物品。 Also, since you're not doing anything extra on the through table, you can remove it;此外,由于您没有在直通表上做任何额外的事情,您可以将其删除; Django will provide one automatically. 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()

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 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.在创建多个外键之前,您必须通过在元数据中添加 unique_togther 属性来声明复合主键。 By following the provided guide you can declare mutiple columns as foreign keys in your django projects按照提供的指南,您可以在 django 项目中将多个列声明为外键

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM