如何使用通过 table 并指向自身的 ManyToManyField 设置 related_name
How to set related_name with a ManyToManyField using a through table and pointing to self
我有一个任务class,它可以有子任务,所以它是一个循环关系。我像这样通过链接器 model/table 传递它:
class Task(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True)
completed = models.BooleanField(default=False)
project = models.ForeignKey('Project', related_name="tasks")
dependancy = models.ManyToManyField('self', through='Dependancy', null=True,
blank=True, through_fields=('task', 'sub_task'), symmetrical=False)
def __str__(self):
return self.title
class Dependancy(models.Model):
task = models.ForeignKey(Task)
sub_task = models.ForeignKey(Task)
但是我得到这个错误:
ERRORS:
gantt_charts.dependency.sub_task: (fields.E303) Reverse query name for 'dependency.sub_task' clashes with field name 'Task.dependency'.
HINT: Rename field 'Task.dependency', or add/change a related_name argument to the definition for field 'dependency.sub_task'.
gantt_charts.dependency.sub_task: (fields.E304) Reverse accessor for 'dependency.sub_task' clashes with reverse accessor for 'dependency.task'.
HINT: Add or change a related_name argument to the definition for 'dependency.sub_task' or 'dependency.task'.
gantt_charts.dependency.task: (fields.E303) Reverse query name for 'dependency.task' clashes with field name 'Task.dependency'.
HINT: Rename field 'Task.dependency', or add/change a related_name argument to the definition for field 'dependency.task'.
gantt_charts.dependency.task: (fields.E304) Reverse accessor for 'dependency.task' clashes with reverse accessor for 'dependency.sub_task'.
HINT: Add or change a related_name argument to the definition for 'dependency.task' or 'dependency.sub_task'.
显然我需要在 Dependency.sub_task 和 Dependency.task 字段上设置相关名称,按照解决方案 here 是将它们命名为 task_task
和 task_sub_task
,但这听起来是错误的、不直观的和令人困惑的。
他们的名字应该是什么?如果我在使用链接 table.
时不对 related_names 是什么感到困惑,那就更容易了
给定一个 Task
实例,您如何访问所有将其作为 task
的 Dependencies
?或者他们的sub_task
?这就是 related_name
的目的——它为 Django 将在 Task
上创建的属性提供名称以指向那组事物。
您看到该错误是因为 Django 自动使用名称 <model>_set
,并且由于您有两个 ForeignKeys
指向同一模型,默认名称将发生冲突。
现在,您可能永远不需要以这种方式直接访问 Dependencies
。如果是这种情况,您可以将 related_name='+'
添加到两个字段,并且根本不会创建反向属性(并且您的错误将消失)。
如果您确实想要访问它们,名称由您决定。我更喜欢更长但更具描述性的名称,以明确其目的。我可能会这样模拟问题:
class Task(models.Model):
subtasks = models.ManyToManyField('self',
through='Dependancy',
symmetrical=False,
through_fields=('supertask', 'subtask'),
related_name='supertasks')
class Dependancy(models.Model):
supertask = models.ForeignKey(Task, related_name='dependencies_as_supertask')
subtask = models.ForeignKey(Task, related_name='dependencies_as_subtask')
class Meta:
unique_together = ('supertask', 'subtask')
>>> task = Task.objects.get()
>>> # all the Tasks that are supertasks of this one
>>> task.supertasks
>>> # all the Tasks that are subtasks of this one
>>> task.subtasks
>>> # all the Dependencies with this Task as the supertask
>>> task.dependencies_as_supertask
>>> # all the Dependencies with this Task as the subtask
>>> task.dependencies_as_subtask
我有一个任务class,它可以有子任务,所以它是一个循环关系。我像这样通过链接器 model/table 传递它:
class Task(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True)
completed = models.BooleanField(default=False)
project = models.ForeignKey('Project', related_name="tasks")
dependancy = models.ManyToManyField('self', through='Dependancy', null=True,
blank=True, through_fields=('task', 'sub_task'), symmetrical=False)
def __str__(self):
return self.title
class Dependancy(models.Model):
task = models.ForeignKey(Task)
sub_task = models.ForeignKey(Task)
但是我得到这个错误:
ERRORS:
gantt_charts.dependency.sub_task: (fields.E303) Reverse query name for 'dependency.sub_task' clashes with field name 'Task.dependency'.
HINT: Rename field 'Task.dependency', or add/change a related_name argument to the definition for field 'dependency.sub_task'.
gantt_charts.dependency.sub_task: (fields.E304) Reverse accessor for 'dependency.sub_task' clashes with reverse accessor for 'dependency.task'.
HINT: Add or change a related_name argument to the definition for 'dependency.sub_task' or 'dependency.task'.
gantt_charts.dependency.task: (fields.E303) Reverse query name for 'dependency.task' clashes with field name 'Task.dependency'.
HINT: Rename field 'Task.dependency', or add/change a related_name argument to the definition for field 'dependency.task'.
gantt_charts.dependency.task: (fields.E304) Reverse accessor for 'dependency.task' clashes with reverse accessor for 'dependency.sub_task'.
HINT: Add or change a related_name argument to the definition for 'dependency.task' or 'dependency.sub_task'.
显然我需要在 Dependency.sub_task 和 Dependency.task 字段上设置相关名称,按照解决方案 here 是将它们命名为 task_task
和 task_sub_task
,但这听起来是错误的、不直观的和令人困惑的。
他们的名字应该是什么?如果我在使用链接 table.
时不对 related_names 是什么感到困惑,那就更容易了给定一个 Task
实例,您如何访问所有将其作为 task
的 Dependencies
?或者他们的sub_task
?这就是 related_name
的目的——它为 Django 将在 Task
上创建的属性提供名称以指向那组事物。
您看到该错误是因为 Django 自动使用名称 <model>_set
,并且由于您有两个 ForeignKeys
指向同一模型,默认名称将发生冲突。
现在,您可能永远不需要以这种方式直接访问 Dependencies
。如果是这种情况,您可以将 related_name='+'
添加到两个字段,并且根本不会创建反向属性(并且您的错误将消失)。
如果您确实想要访问它们,名称由您决定。我更喜欢更长但更具描述性的名称,以明确其目的。我可能会这样模拟问题:
class Task(models.Model):
subtasks = models.ManyToManyField('self',
through='Dependancy',
symmetrical=False,
through_fields=('supertask', 'subtask'),
related_name='supertasks')
class Dependancy(models.Model):
supertask = models.ForeignKey(Task, related_name='dependencies_as_supertask')
subtask = models.ForeignKey(Task, related_name='dependencies_as_subtask')
class Meta:
unique_together = ('supertask', 'subtask')
>>> task = Task.objects.get()
>>> # all the Tasks that are supertasks of this one
>>> task.supertasks
>>> # all the Tasks that are subtasks of this one
>>> task.subtasks
>>> # all the Dependencies with this Task as the supertask
>>> task.dependencies_as_supertask
>>> # all the Dependencies with this Task as the subtask
>>> task.dependencies_as_subtask