Django:应用“相同的父”约束到ManyToManyField映射到self [英] Django: apply "same parent" constraint to ManyToManyField mapping to self

查看:593
本文介绍了Django:应用“相同的父”约束到ManyToManyField映射到self的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a model where tasks are pieces of work that each may depend on some number of other tasks to complete before it can start. Tasks are grouped into jobs, and I want to disallow dependencies between jobs. This is the relevant subset of my model:

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,但仔细检查它似乎需要一个静态查询,而不是依赖于这个任务对象中的值。

Is there any way I can express the constraint that all prerequisite tasks must have the same job? I could enforce this at the view level, but I would really like to get it to work at the model level so that the admin interface will display appropriate options when choosing prerequisites for a task. I thought I could use "limit_choices_to", but on closer inspection it seems to require a static query, not something dependent on the values in this task object.

推荐答案

这里有两个单独的问题。

There are two separate issues here.

如果你想在模型层执行这个约束,你可能需要定义一个明确的 模型并覆盖它的save()方法(你不能只是重写Task.save(),因为不一定被调用来添加条目到M2M)。 Django 1.2将有一个更完整的模型验证框架,更像是表单验证。

If you want to enforce this constraint at the model level, you might have to define an explicit "through" model and override its save() method (you can't just override Task.save() as that isn't necessarily invoked for adding entries to an M2M). Django 1.2 will have a fuller model validation framework, more like form validation.

如果你只想要在管理中出现某些选择,这是一个窗体级问题。您可以在窗体的 init 方法中动态设置ModelMultipleChoiceField的查询集属性:

If you want only certain choices to appear in the admin, that's a form-level issue. You can dynamically set the queryset attribute of the ModelMultipleChoiceField in a form's init method:

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没有);因为一个新的任务还没有工作,你想要什么样的可用先决条件没有明确定义。

You may need to introduce some additional checking here to handle the case of creating a new Task (in that case "self.instance.job" will likely be None); what set of available prerequisites you want there is not clearly defined, since a new Task doesn't yet have a job.

这篇关于Django:应用“相同的父”约束到ManyToManyField映射到self的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆