2011-06-29 3 views
2

Я новичок в Django и MySQL, поэтому извиняюсь, если это заканчивается простым вопросом.Django: нужна помощь с схемой DB (ManyToMany, отношения ForeignKey)

Я работаю над сайтом по управлению проектами. Скажем, у нас есть Program. Каждая программа имеет некоторое количество Milestones, которые, в свою очередь, имеют некоторое количество Tasks, которые должны быть заполнены для достижения Milestone. Вехи будут одинаковыми в разных программах, но нет гарантии, что задачи, требуемые для каждой вехи, останутся неизменными во всех программах.

Вот (сокращенно) 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 имеет Milestone А, и Программа 2 также имеет Milestone А.
  • Добавление задачи в Программе 1 по Milestone А.
  • нежелательные последствия: задача теперь также прилагается к программе 2 в Milestone А.

Решение может состоять в том, чтобы создать две «Milestone A» в базе данных Milestone: две разные строки, которые разделяют имя «Milestone A.», Однако, учитывая, что они будут отличаться только в id, будучи тем же концептуальным предметом, это кажется пустой тратой.

Другая идея может быть требовать одновременно ProgramID и MilestoneID при добавлении нового Task, но я не уверен, что можно было бы добавить новые задачи в Django администратора - то есть, как пройти ProgramID Программы что пользователь в настоящее время смотрит.

Как я могу адаптировать мой models.py, чтобы программы могли делиться вехами, имея набор задач для каждой задачи для каждого этапа (т. Е. Избегая описанного выше сценария)?

ответ

1

Так как вы хотите Задачи, связанные с Milestone Программы и не Вехи, вы могли бы изменить задачу класса на:

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

О Боже, я даже не знаю, что вы могли бы связать ForeignKey с сквозные таблицы. У меня такое чувство, что это то, что я искал, но я проверю, чтобы убедиться и дать вам тик, если это так. Благодаря! –

0

С моей (вне) точки зрения, номенклатура не совсем то, что вы хотите быть определение схемы вашей базы данных. Веха A под Программой 1 кажется, хотя она именована тем же самым, может иметь совершенно другой набор Заданий как «тот же» этап A под Программой 2.

Я предлагаю вам различать имя ключа и отображаемое имя. Например, на модели Milestone вы можете иметь 2 имени: MilestoneKey, которые будут внутренне использоваться и храниться как нечто вроде «Project 1 Milestone A» и MilestoneName, что было бы похоже на «Milestone A».

В вашем приложении пользователи будут видеть только MilestoneName, тогда как внутренне вы можете отслеживать его как MilestoneKey.

Или, чтобы избежать этой сложности, просто поле MilestoneName и вызвать программу 2 в Milestone А становится Milestone X, или Программа 2 - Milestone А.

Смежные вопросы