Django:需要DB模式的帮助(ManyToMany,ForeignKey关系)

时间:2011-06-29 20:27:59

标签: mysql django

我是Django和MySQL的新手,所以如果这最终成为一个简单的问题我会道歉。

我正在开发一个项目管理网站。假设我们有Program。每个程序都有一些Milestones,其中有一些Tasks需要完成才能达到里程碑。不同计划的里程碑将是相同的,但无法保证每个里程碑所需的任务在各计划之间保持不变。

这是(缩写)models.py

class Program(models.Model):
    # ...
    complete = models.BooleanField()
    milestones = models.ManyToManyField(Milestone, through='ProgramMilestone')

class Milestone(models.Model):
    # ...

class Task(models.Model):
    # ...
    complete = models.BooleanField()
    milestone = models.ForeignKey(Milestone)

class ProgramMilestone(models.Model):
    # ...
    complete = models.BooleanField()
    program = models.ForeignKey(Program)
    milestone = models.ForeignKey(Milestone)

我有...through='ProgramMilestone'因为Programs应该被允许共享Milestones但是具有每个程序的完成状态。

此架构的问题是这样的:

  • 我们有两个程序,程序1和程序2。
  • 程序1有里程碑A,程序2也有里程碑A.
  • 将任务添加到程序1的里程碑A。
  • 不必要的后果:该任务现在也附在计划2的里程碑A上。

解决方案可能是在里程碑数据库中创建两个“里程碑A”:两个不同的行共享名称“里程碑A”。但是,考虑到id只是在同一个概念项目中它们不同,这似乎是浪费。

另一个想法可能是在添加新ProgramID时需要MilestoneIDTask,但我不确定是否可以在Django Admin中添加新任务 - 也就是说,如何传递用户当前正在查看的程序的ProgramID

我如何调整models.py以便程序可以共享里程碑,同时为每个里程碑设置每个程序的任务组(即避免上述情况)?

2 个答案:

答案 0 :(得分:1)

由于您希望将任务与程序的里程碑相关联而不是与里程碑相关,因此您可以将类任务更改为:

class Task(models.Model):
    # ...
    complete = models.BooleanField()
    programMilestone = models.ForeignKey(ProgramMilestone)

答案 1 :(得分:0)

从我的(外部)角度来看,命名法并不是你想要定义数据库模式的真正原因。程序1下的里程碑A似乎虽然命名相同,但可以将一组完全不同的任务作为程序2下的“相同”里程碑A。

我建议你做的是区分键名和显示名。例如,在Milestone模型上,您可以有两个名称:MilestoneKey,它将在内部使用并存储为“Program 1 Milestone A”和MilestoneName,类似于“里程碑A”。

在您的应用程序中,用户只能看到MilestoneName,而在内部,您可以将其跟踪为MilestoneKey。

或者,为了避免这种复杂性,只需拥有MilestoneName字段并调用程序2的里程碑A成为里程碑X,或程序2 - 里程碑A.

相关问题