我已经搜索了一段时间,但似乎无法找到这个问题的现有问题(虽然它可能是一个不知道术语的问题)。在Django中建模异构多对多关系的最佳方式是什么?
我是Django的新手,并且一直在尝试采用一种应该随着时间的推移非常可扩展的设计,并使其与Django的ORM协同工作。实质上,它是一系列使用共享联结表的多对多关系。
该设计是一个通用的游戏制作系统,它说:“如果您满足[需求],您可以使用[成本]作为材料创建[奖励]。”这样可以使用同一个系统从任意数量的商店出售物品,并且通用性足以支持各种机械 - 我曾经见过它成功使用过。
Django不支持多个M2M关系共享相同结表(显然是因为它没有办法制定出反向关系),所以我似乎有下列选项:
- 让它打造自己的结点表,最终为六个或更多,或者
- 使用外键代替内置MTM关系的结点表。
第一个选项有点乱,因为我知道我最终必须将其他字段添加到联结表中。第二个选项工作得很好。不幸的是,因为没有从联结表返回到其他每个表的外键,所以我经常与管理系统对抗,以便让它按照我的意愿去做。
下面是受影响的机型:
class Craft(models.Model):
name = models.CharField(max_length=30)
description = models.CharField(max_length=300, blank=True)
cost = models.ForeignKey('Container', related_name="craft_cost")
reward = models.ForeignKey('Container', related_name="craft_reward")
require = models.ForeignKey('Container', related_name="craft_require")
class ShopContent(models.Model):
shopId = models.ForeignKey(Shop)
cost = models.ForeignKey('Container', related_name="shop_cost")
reward = models.ForeignKey('Container', related_name="shop_reward")
require = models.ForeignKey('Container', related_name="shop_require")
description = models.CharField(max_length=300)
class Container(models.Model):
name = models.CharField(max_length=30)
class ContainerContent(models.Model):
containerId = models.ForeignKey(Container, verbose_name="Container")
itemId = models.ForeignKey(Item, verbose_name="Item")
itemMin = models.PositiveSmallIntegerField(verbose_name=u"min amount")
itemMax = models.PositiveSmallIntegerField(verbose_name=u"max amount")
weight = models.PositiveSmallIntegerField(null=True, blank=True)
optionGroup = models.PositiveSmallIntegerField(null=True, blank=True,
verbose_name=u"option group")
有没有更简单,容易明显的方式来得到这个工作?我试图允许从Craft编辑界面上的每个相关列内联编辑ContainerContent信息。
链接的另一个版本:http://stackoverflow.com/questions/10115137/in-the-django-admin-is-there-a-way-to- show-a-list-of-actual-links-to-a-models – agf 2012-04-12 19:56:49
嵌套内联信息非常有用。我编辑了这个问题,以显示关系问题稍好一些,但是多个表格将会经历这个问题。不过,如果我最终这样做,它会减少三分之一所需的桌子数量! – ThreeHams 2012-04-12 19:57:02
@ThreeHams好的,如果你有多次相同的关系,你只需要建模一次。要么像我的例子那样推广到单个模型,要么使用显式的'OneToOne'字段,或者使用带有子类的隐式'OneToOne'字段。 – agf 2012-04-12 20:23:14