如何使用through表将Many_name设置为ManyToManyField并指向self

时间:2015-01-21 15:58:38

标签: django django-models

我有一个任务类,可以有子任务,所以它是一个循环关系。我通过链接器模型/表传递它,如下所示:

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_tasktask_sub_task,但是这听起来不对,不直观,令人困惑。

对他们来说,一个简洁明了的名字是​​什么?如果我在使用链接表时没有对related_names的内容感到困惑,那会更容易。

1 个答案:

答案 0 :(得分:3)

如果有Task个实例,您如何访问所有Dependenciestask?或者他们的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