问题
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)
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.
回答1:
There are two separate issues here.
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.
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)
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.
来源:https://stackoverflow.com/questions/1531065/django-apply-same-parent-constraint-to-manytomanyfield-mapping-to-self