我正在尝试为以下场景创建模型:
项目已交付,必须按特定顺序传递各种任务。 项目一旦通过任务,任务就会标记为已完成。 任务的名称是事先知道的。
例如:
- 创建项目
- 任务1'注册项目'
- 任务2'安装项目'
- 任务3'检查项目'
的日志
我开始使用这样一个简单的模型,但它看起来非常静态,而不是我正在寻找的东西。
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)
尝试关系字段,例如用于预定义任务的ManyToMany字段,我最终得到了这个:
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)
但是,如果我创建两个具有相同任务的项目并将第一个项目的任务标记为已完成,那么它将在第二个项目中标记为已完成 - 这不是我想要的。
如何将任务分配给特定项目?或者哪种其他模型最适合我的情景?
答案 0 :(得分:1)
为了在对象创建时执行代码,通常会覆盖save()方法。因此,当创建一个Item时,在save()方法中创建并动态地将Tasks链接到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)我仍然检查它是否是一个新实例,然后调用super save然后我为这个项目创建任务。
确保检查self.pk值,否则在更新对象时代码也会被执行。
还要注意,每次都必须创建一个链接到Item对象的新Task对象。如果您将一个任务对象链接到两个项目,那么当item_a完成一个任务时,该任务似乎也会对item_b完成。
您需要做的是为item_a创建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