Здесь модель UserTask
была создана только с целью уменьшения избыточности в базе данных.
Если я правильно понимаю, Task
принадлежит single User
, по крайней мере, на основе вашего комментария:
Я читал о ManyToMany, проблема в том, что это отношение на самом деле OneToMany.
В этом случае я не вижу, как вы «уменьшаете» избыточность в базе данных, фактически вы создаете дополнительное дублирование данных , поскольку теперь вам нужно сохранить Task
и user = ForeignKey(..)
в гармонии с UserTask
, таким образом, это означает, что все создания, изменения и удаления имеют влияние, а некоторые обходят сигнальные инструменты Django, поэтому это делает его довольно сложным, если не невозможным.
Дело в том, что вам не нужно для построения таблицы для запроса отношения в обратном порядке.По умолчанию Django помещает базу данных index в ForeignKey
, поэтому база данных может эффективно извлекать Task
s, которые принадлежат одному (или нескольким) пользователям, таким образом, она делает JOIN
стаблица user
более эффективна.
Как правило, каждый определяет ForeignKey
как:
class Task(models.Model):
text = models.TextField()
dueDate = models.DateField()
<b>user = models.ForeignKey(User, on_delete=models.CASCADE)</b>
priority = models.CharField(choices = PRIORITIES, default = "LOW")
На уровне Python / Django, Django также обеспечивает удобство для получения задачUser
.Если вы хотите получить все Task
из some_user
, вы можете запросить:
some_user.<b>task_set</b>.all()
или выполнить фильтрацию по задачам, например:
some_user.<b>task_set</b>.filter(text__icontains='someword')
YouМожно также сделать имя отношения в обратном направлении более удобным, указав related_name
в ForeignKey
, например:
class Task(models.Model):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
<b>related_name='tasks'</b>
)
text = models.TextField()
dueDate = models.DateField()
priority = models.CharField(choices = PRIORITIES, default = "LOW")
В этом случае вы, таким образом, запрашиваете Task
sUser
с:
some_user.<b>tasks</b>.all()
Однако существует сценарий, в котором Django создает неявную модель, которая связывает две модели вместе: в случае, если одна определяет ManyToManyField
[Django-doc] , поскольку указание массива идентификаторов обычно сложно (или даже невозможно) для большого количества реляционных баз данных (даже если это возможно, как правило, больше нельзя гарантировать ограничения FOREIGN KEY
) и т. д.
Если отношение «многие ко многим» между двумя моделями содержит дополнительные данные (например, метку времени, когда два пользователя стали друзьями), то одна даже определяет явную модель с двумя ForeignKey
отношениями (и дополнительными атрибутами),и использует это как through
[Django-doc] модель.