Django: применить ограничение «одного и того же родителя» к сопоставлению ManyToManyField для себя

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

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

One Solution collect form web for “Django: применить ограничение «одного и того же родителя» к сопоставлению ManyToManyField для себя”

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

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

  • Как проверить типы данных столбцов в ORM SQLAlchemy?
  • SQL Alchemy ORM возвращает один столбец, как избежать обычной обработки сообщений
  • Django: следовать отношениям назад
  • Использование только части DB Django
  • Повторное подключение MySQL к таймауту
  • Как организовать уровень доступа к базе данных?
  • Использовать хранилище данных Google AppEngine вне проекта AppEngine
  • Стратегии ускорения операций ORM в Django
  • Python - лучший язык программирования в мире.