访问django中的反向关系字段

时间:2017-08-29 11:01:51

标签: python django django-models django-views foreign-keys

我有这些模特:

class Task(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField()

class Report(models.Model):
    task = models.ForeignKey(
        Task, blank=True, null=True, related_name='+')
    status = models.CharField(max_length=32, choices=Status.CHOICES, default=Status.INCOMPLETE)

现在我想获得所有Task及其相关状态。

我该怎么做?

3 个答案:

答案 0 :(得分:1)

首先,'+'不是有效的related_name。它也不是很明确。

请尝试将'+'替换为'reports'

# ...

class Report(models.Model):
    task = models.ForeignKey(
        Task,
        blank=True,
        null=True,
        related_name='reports'  # <<<
    )
    status = models.CharField(
        max_length=32,
        choices=Status.CHOICES,
        default=Status.INCOMPLETE
    )

然后,要获取所有Task及其相关状态,您可以使用values

>>> Task.objects.values('name', 'report__status')
<QuerySet [{'name': 'test', 'report__status': 'OK'}, ...]>

答案 1 :(得分:0)

related_name的值更改为其他内容,例如'reports'

class Report(models.Model):
    task = models.ForeignKey(
        Task, blank=True, null=True, related_name='reports')
    status = models.CharField(max_length=32, choices=Status.CHOICES, default=Status.INCOMPLETE)

现在,如果您有一个Task对象(不是queryset),您可以使用以下命令获取其报告的查询集:

reports = task.reports.all()

如果需要,您可以在reports上使用过滤器()。

reports = task.reports.filter(status='something')

答案 2 :(得分:0)

在这种情况下,代码+正是您不想拥有的related_name。它告诉Django不要创建向后关系。查看here。选择另一个有效名称或跳过此参数,在这种情况下,Django将默认使用后向关系的名称创建反向关系,模型名称小写和后缀_set(有关详细信息,请参阅here

但是,在您的示例中,如果要获取与任务相关的所有报告以及相应的状态,则不一定需要向后关系。试试这个:

reports = Report.objects.exclude(task__isnull=True).values('task__name', 'status')