Django:将“相同父”约束应用于ManyToManyField映射到self

时间:2009-10-07 11:32:12

标签: python django orm constraints

我有一个模型,其中任务是工作的一部分,每个工作可能依赖于在开始之前完成的一些其他任务。任务分组到作业中,我想禁止作业之间的依赖关系。这是我模型的相关子集:

class Job(models.Model):
    name = models.CharField(max_length=60, unique=True)

class Task(models.Model):
    job = models.ForeignKey(Job)
    prerequisites = models.ManyToManyField(
        'self',
        symmetrical=False,
        related_name="dependents",
        blank=True)

有什么方法可以表达所有必备任务必须具有相同工作的约束?我可以在视图级别强制执行此操作,但我真的希望让它在模型级别工作,以便管理界面在选择任务的先决条件时显示适当的选项。我以为我可以使用“limit_choices_to”,但仔细观察它似乎需要一个静态查询,而不是依赖于此任务对象中的值。

1 个答案:

答案 0 :(得分:3)

这里有两个不同的问题。

如果要在模型级别强制执行此约束,则可能必须定义显式“直通”模型并覆盖其save()方法(您不能仅覆盖Task.save(),因为它不是必须调用以向M2M添加条目)。 Django 1.2将拥有更全面的模型验证框架,更像是表单验证。

如果您只想在管理员中显示某些选项,那就是表单级问题。您可以在表单的 init 方法中动态设置ModelMultipleChoiceField的queryset属性:

class TaskForm(forms.ModelForm):
   class Meta:
      model = Task

   def __init__(self, *args, **kwargs):
      super(TaskForm, self).__init__(*args, **kwargs)
      self.fields['prerequisites'].queryset = Task.objects.filter(job=self.instance.job)

您可能需要在此处引入一些额外的检查来处理创建新任务的情况(在这种情况下,“self.instance.job”可能是None);你想要的那些可用先决条件集没有明确定义,因为新任务还没有工作。