我已經搜索了一段時間,但似乎無法找到這個問題的現有問題(雖然它可能是一個不知道術語的問題)。在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