2017-10-21 68 views
1

我试图创建以下情形的典范项目:Django模型 - 创造出必须通过各种任务

的项目进行输送,具有通过各种任务,按照一定的顺序通过。 只要项目通过任务,该任务就被标记为已完成。 任务的名称是事先已知的。

例如:

  • 创建项目
  • 任务1 '注册项目'
  • 任务2 '安装项目'
  • 任务3 '检查项目的日志'

我从一个像这样的简单模型开始,b它对我来说看起来很静,而不是我真正想要的。

models.py

class Item(models.Model): 

    item_id = models.PositiveIntegerField() 
    item_priority = models.PositiveSmallIntegerField(default=2) 
    item_date_created = models.DateField(auto_now_add=True) 

    task1_name = models.CharField(max_length=128) 
    task1_done_by = models.CharField(max_length=64, blank=True) 
    task1_done_date = models.DateField(null=True, blank=True) 

    task2_name = models.CharField(max_length=128) 
    task2_done_by = models.CharField(max_length=64, blank=True) 
    task2_done_date = models.DateField(null=True, blank=True) 

    # ... next 20 tasks 

    def __str__(self): 
     return str(self.item_id) 

试图关系领域,例如多对多字段预先定义的任务,我结束了这一点:

class Task(models.Model): 

    name = models.CharField(max_length=128) 
    done_by = models.CharField(max_length=64, blank=True) 
    done_date = models.DateField(null=True, blank=True) 


class Item(models.Model): 

    item_id = models.PositiveIntegerField() 
    item_priority = models.PositiveSmallIntegerField(default=2) 
    item_date_created = models.DateField(auto_now_add=True) 
    tasks = models.ManyToManyField(Task) 

但是,如果我创建了两个项目进行相同的任务和第一项的任务标记为完成它将被标记为第二项中的完成 - 这不是我想要的。

如何将任务分配给特定项目?或者哪个其他模型最适合我的场景?

回答

1

为了在创建对象时执行代码,您通常会覆盖save()方法。因此,一个项目被创建时,在save()方法创建和动态链接的任务Item.tasks

class Item(models.Model): 
    item_id = models.PositiveIntegerField() 
    item_priority = models.PositiveSmallIntegerField(default=2) 
    item_date_created = models.DateField(auto_now_add=True) 

    # remove m2m !!! 

    def save(self, *args, **kwargs): 
     # If it has no pk then it is a *new* item 
     if not self.pk: 

      # Save by manually 
      # Call save of parent class (models.Model) creating the custom class 
      super(Item, self).save(*args, **kwargs) 

      # Now you have the PK 
      t1 = Task(name='T1', item=self) 
      t1.save() 
      #... 

class Task(models.Model): 
    name = models.CharField(max_length=128) 
    done_by = models.CharField(max_length=64, blank=True) 
    done_date = models.DateField(null=True, blank=True) 

    # Add Item FK 
    item = models.ForeignKey(Item) 

注上的代码更新:

1)我改变了方向:任务链接到物品,而不是相反。见https://docs.djangoproject.com/en/1.11/topics/db/examples/many_to_one/

2)我仍然检查它是否是一个新的实例,然后调用超级保存,然后我创建此项目的任务。

确保检查self.pk值,否则在更新对象时也会执行代码。

另外请注意,您必须每次创建一个链接到Item对象的新Task对象。如果您将一个任务对象链接到两个项目,那么当item_a完成一项任务时,该任务似乎也将为item_b完成。

您需要做的是为item_b创建item1的task1和item_b的task2。这样你分开的任务。

往下看:

https://docs.djangoproject.com/en/1.11/ref/models/instances/#saving-objects

https://docs.djangoproject.com/en/1.11/topics/db/models/#relationships

+0

我已经调整了我的问题有点澄清我的问题:如果我创建两个项目具有相同的任务和标记的第一项任务完成后,它会在第二项中标记为已完成 - 这不是我想要的,我正在寻找解决方案。 –

+1

类Item(models.Models)是数据库对象的模板。您可以从中创建实例。如果您将一个任务实例链接到两个项目实例并更新任务,则链接到这两个项目的链接将会相同。你需要做的是为item1创建task1,为item2创建task2。这样你分开的任务。 – rollinger

+0

我开始明白了。我必须创建新任务并将其链接到每个新项目,并且不能重复使用它们。你碰巧有一个手动创建和添加任务的代码示例吗? –