1

我已经搜索了一段时间,但似乎无法找到一个现有的问题(尽管这可能是不知道术语的问题)。

我是 Django 的新手,并且一直在尝试采用随着时间的推移应该非常可扩展的设计,并使其与 Django 的 ORM 一起使用。本质上,它是一系列使用共享连接表的多对多关系。

该设计是一个通用的游戏制作系统,上面写着“如果你满足[要求],你可以使用[成本]作为材料来创造[奖励]。” 这允许使用相同系统从任意数量的商店出售物品,并且通用性足以支持广泛的机制 - 我在过去看到它成功使用过。

Django 不支持共享同一个联结表的多个 M2M 关系(显然是因为它无法计算出反向关系),所以我似乎有以下选项:

  • 让它创建自己的联结表,最终有六个或更多,或者
  • 使用联结表的外键代替内置的 MTM 关系。

第一个选项有点混乱,因为我知道我最终必须在联结表中添加额外的字段。第二个选项效果很好。不幸的是,因为没有从联结表 BACK 到其他每个表的外键,我一直在与管理系统作斗争,以让它做我想做的事。

以下是受影响的型号:

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 信息进行内联编辑。

4

2 回答 2

3

听起来您有一种“交易”,它具有名称、描述和类型,并定义了成本、奖励和要求。您应该将其定义为单个模型,而不是多个模型(ShopContentCraft等)。

class Transaction(models.Model):
    TYPE_CHOICES = (('Craft', 0),
                    ('Purchase', 1),
                   )
    name        = models.CharField(max_length=30)
    description = models.CharField(max_length=300, blank=True)
    cost        = models.ForeignKey('Container')
    reward      = models.ForeignKey('Container')
    require     = models.ForeignKey('Container')
    type        = models.IntegerField(choices = TYPE_CHOICES)

现在Shopetc. 可以有一个ManyToManyFieldto Transaction

无论您是否使用此特定模型,costreward关系require都应该在一个地方 - 如上所述,或者OneToOne与 等关系CraftShopContent正如您所猜测的,您不应该有一大堆复杂的多对多through完全一样的表。


您在帖子底部提到您是

试图允许对编辑界面ContainerContent上每个相关列的信息进行内联编辑。Craft

如果您正在建模多个级别的关系,并使用管理应用程序,您将需要应用某种嵌套的内联补丁,或者使用某种链接方案,例如我在最近的问题中使用的那种,我该怎么做添加从一个对象的 Django 管理页面到相关对象的管理页面的链接?

于 2012-04-12T19:26:31.547 回答
1

我在这里到的东西太复杂了,但我可能错了。作为开始,这会更好吗?(ContainerContent稍后会弄清楚)

class Cost(models.Model):
    name        = models.CharField(max_length=30)

class Reward(models.Model):
    name        = models.CharField(max_length=30)

class Require(models.Model):
    name        = models.CharField(max_length=30)

class Craft(models.Model):
    name        = models.CharField(max_length=30)
    description = models.CharField(max_length=300, blank=True)
    cost        = models.ForeignKey(Cost)
    reward      = models.ForeignKey(Reward)
    require     = models.ForeignKey(Require)

class Shop(models.Model):
    name        = models.CharField(max_length=30)
    crafts      = models.ManyToMany(Craft, blank=True)
于 2012-04-12T21:47:19.703 回答