我已经搜索了一段时间,但似乎无法找到现有的问题(尽管这可能是一个不了解术语的问题)。
我是Django的新手,并且一直试图采用一种随着时间推移应该非常容易扩展的设计,并使其与Django的ORM一起使用。从本质上讲,它是使用共享联结表的一系列多对多关系。
该设计是一个通用的游戏制作系统,它说“如果你遇到[要求],你可以用[费用]作为材料来创造[奖励]。”这允许物品使用相同的系统从任意数量的商店出售,并且足够通用以支持各种机制 - 我已经看到它在过去成功使用过。
Django不支持共享相同联结表的多个M2M关系(显然因为它无法解决反向关系),所以我似乎有这些选项:
第一个选项有点混乱,因为我知道我最终必须在连接表中添加其他字段。第二种选择非常有效。不幸的是,因为从联结表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信息。
答案 0 :(得分:3)
听起来你有一种“交易”,它有一个名称,描述和类型,并定义了成本,奖励和要求。您应该将其定义为单个模型,而不是多个模型(ShopContent
,Craft
等。)
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)
现在Shop
等可以有一个ManyToManyField
到Transaction
。
无论您是否使用此特定模型,cost
,reward
和require
关系都应位于一个位置 - 如上所述,或OneToOne
关系中使用Craft
,ShopContent
等。正如您所猜测的那样,您不应该拥有一大堆复杂的多对多through
表,这些表都非常相同。
你在帖子的底部提到你是
尝试允许在
ContainerContent
修改界面上的每个相关列中内联编辑Craft
个信息。
如果你正在建模几个级别的关系,并使用管理员应用程序,你需要应用某种nested inline补丁,或使用某种链接方案,就像我在我使用的那种最近的问题,How do I add a link from the Django admin page of one object to the admin page of a related object?
答案 1 :(得分:1)
我smelling这里的事情太复杂了,但我可能错了。作为一个开始,
这更好吗? (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)