У меня есть эти модели:

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 и их статус.

Как мне это сделать?

0
user3334294 29 Авг 2017 в 14:01

3 ответа

Лучший ответ

Во-первых, '+' не является допустимым 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
wencakisa 29 Авг 2017 в 12:18

Измените значение 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 (не набор запросов), вы можете получить набор запросов из его отчетов, используя:

reports = task.reports.all()

Вы можете использовать filter () для reports, если вам нужно.

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

0
Brian H. 29 Авг 2017 в 12:12

Знак + - это именно то, что вы не хотите иметь в качестве related_name в этом случае. Он говорит Джанго не создавать обратную связь. Ознакомьтесь с здесь, Выберите другое допустимое имя или пропустите этот аргумент, и в этом случае Django по умолчанию создаст обратное отношение, используя для имени обратного отношения имя модели в нижнем регистре и суффикс _set (см. здесь для получения подробной информации).

Однако, в вашем примере, если вы хотите получить все отчеты, которые связаны с задачей и соответствующим статусом, вам необязательно нужны обратные связи. Попробуй это:

reports = Report.objects.exclude(task__isnull=True).values('task__name', 'status')
0
gkaravo 30 Авг 2017 в 17:04