Django: применить ограничение "тот же родительский" для сопоставления ManyToManyField к себе - PullRequest
3 голосов
/ 07 октября 2009

У меня есть модель, в которой задачи - это части работы, каждая из которых может зависеть от некоторого числа других задач, которые нужно выполнить, прежде чем она может начаться. Задачи сгруппированы в задания, и я хочу запретить зависимости между заданиями. Это соответствующее подмножество моей модели:

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 Ответ

3 голосов
/ 07 октября 2009

Здесь есть два отдельных вопроса.

Если вы хотите применить это ограничение на уровне модели, вам, возможно, придется определить явную сквозную модель и переопределить ее метод save () (вы не можете просто переопределить Task.save (), так как это не так. обязательно вызывается для добавления записей в M2M). Django 1.2 будет иметь более полную структуру проверки модели, больше похожую на проверку формы.

Если вы хотите, чтобы в администраторе отображались только определенные варианты, это проблема уровня формы. Вы можете динамически установить атрибут queryset для ModelMultipleChoiceField в методе init формы:

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», вероятно, будет Нет); какой набор доступных предварительных условий вам нужен, четко не определен, поскольку у новой задачи еще нет задания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...