Двойные отношения "многие-ко-многим" в SQL с использованием только двух таблиц
Имея две таблицы, одна из которых называется Задачи, а другая Связи, где каждая задача в Задачах может иметь 0-ко-многим предшественников и аналогично, 0-ко-многим преемникам, что отношения между задачами хранятся в Relations-таблице.
Итак, если задача_1 является предшественником задачи_2, а задача_2 является предшественником задачи_3, то я хотел бы сохранить следующие записи в Relation-table:
pk | predecessor | successor |
---|---|---|
0 | 1 | 2 |
1 | 2 | 3 |
например, используя определение модели Django:
class Tasks(models.Model):
name_text = models.CharField(max_length=200)
duration_int = models.IntegerField(default=1)
class Relations(models.Model):
predecessors = models.ManyToManyField(Tasks)
successors = models.ManyToManyField(Tasks)
К сожалению, это не работает. Я считаю, что это потому, что давать определение для successors как еще одно отношение к Tasks, которое уже существует, может быть неуместно; хотя я также считаю, что Relation-table должна каскадировать обратно в Task-table с обоими отношениями: с предшественником и с преемниками тоже, чтобы обеспечить целостность.
Не мог бы кто-нибудь из вас помочь мне с этой проблемой?
Поскольку вы связываете два поля с одной моделью, добавьте разные связанные имена для ManyToManyField.
predecessors = models.ManyToManyField(Tasks, related_name='tasks_predecessors_set')
successors = models.ManyToManyField(Tasks)
Рекурсивные отношения, использующие промежуточную модель, не могут определять имена обратных аксессоров, так как они будут одинаковыми. Вам нужно установить related_name хотя бы для одного из них. Если вы предпочитаете, чтобы Django не создавал обратное отношение, установите related_name в '+'.
Моделирование не имеет особого смысла, вы используете два ForeignKey
поля [Django-doc] для предшественника и преемника:
class Task(models.Model):
name_text = models.CharField(max_length=200)
duration_int = models.IntegerField(default=1)
successors = models.ManyToManyField(
Task,
through='Relation',
through_fields=('predecessor', 'sucessor'),
related_name='predecessor',
)
class Relation(models.Model):
predecessor = models.ForeignKey(
Task, on_delete=models.CASCADE, related_name='successor_relations'
)
successor = models.ForeignKey(
Task, on_delete=models.CASCADE, related_name='successor_relations'
)
Большое спасибо за каждый ответ, каждое предложенное решение работает хорошо
Позвольте мне вернуться к этой теме... Итак, я выполнил вышеуказанные инструкции, миграция выполнена, но почему-то отношения не могут быть предоставлены.
class Tasks(models.Model):
name_text = models.CharField(max_length=200)
duration_int = models.IntegerField(default=1)
relations = models.ManyToManyField(
'Tasks',
through='Relations',
through_fields=('predecessors', 'successors'),
related_name='whatever',
)
class Relations(models.Model):
predecessors = models.ForeignKey(
Tasks, on_delete=models.CASCADE, related_name='predecessors_relations',
)
successors = models.ForeignKey(
Tasks, on_delete=models.CASCADE, related_name='successors_relations',
)
Используя оболочку, предоставляемую Django, задачи можно создавать и сохранять, но это не относится к отношениям. Используя пример Django Example я считаю, что "relation" является частью задач, например, имея две задачи, уже имеющиеся в БД:
>>> from simo.models import Relations
>>> from simo.models import Tasks
>>> t1 = Tasks.objects.filter(id=1)
>>> t2 = Tasks.objects.filter(id=2)
>>> r1 = Relations()
Но какое бы решение я не пытался сохранить отношение r1, оно выдает ошибку синтаксиса; даже если его попытаться сохранить как t1.relations(...), оно просто не будет принято.
Не могли бы вы помочь советом?
Спасибо