Я делаю сложные запросы LEFT JOIN, но я не уверен, как извлечь информацию из объединенных таблиц. Я вижу множество примеров, которые используют LEFT JOIN для фильтрации результатов, но я не вижу никого, кто бы получал доступ к каким-либо значениям строки из LEFT JOIN. Во-первых, давайте начнем с нескольких упрощенных примеров моделей в качестве примера:
class Bar(models.Model):
name = models.CharField(max_length=255)
status = models.IntegerField(default=0)
data = models.TextField(default=None)
class Meta:
db_table = 'bar'
class FooBar(models.Model):
bar = models.ForeignKey(Bar, on_delete=models.CASCADE, related_name='foobars')
status = models.IntegerField(default=0)
data = models.TextField(default=None)
class Meta:
db_table = 'foobar'
class FuBar(models.Model):
bar = models.ForeignKey(Bar, on_delete=models.CASCADE, related_name='fubars')
status = models.IntegerField(default=0)
data = models.TextField(default=None)
class Meta:
db_table = 'fubar'
Таблица Bar
имеет отношение «один ко многим» с таблицами FooBar
и FuBar
. Это также означает, что FooBar
и FuBar
имеют неявное отношение «многие ко многим».
Вот RAW-эквивалент того, что я пытаюсь сделать:
SELECT
foobar.id,
foobar.status,
foobar.data,
bar.id,
bar.status,
bar.data,
fubar.id,
fubar.status,
fubar.data
FROM foobar
JOIN bar ON bar.id = foobar.bar_id
LEFT JOIN fubar ON fubar.bar_id = bar.id
WHERE
foobar.status = 1
AND bar.status = 1
AND fubar.status = 1;
Когда я смотрю на каждую запись в табличном наборе результатов, у меня есть вся информация для идентификации отдельных записей FooBar, Bar и Fubar, связанных с каждой строкой, и всех их значений столбцов. Давайте предположим, что мне нужно иметь доступ к каждому из этих столбцов в наборе результатов после завершения запроса.
Я могу воспроизвести те же самые соединения в Django:
q = (FooBar.objects
.filter(status=1,
bar__status=1,
bar__fubars__status=1)
.select_related('bar'))
Если я перебираю набор результатов, я могу получить доступ к объектам FooBar и Bar без необходимости выполнять какие-либо дополнительные запросы неявно или явно. Следующий фрагмент кода иллюстрирует, как я могу получить доступ к их информации.
for fb in q:
foobar = fb
foobar_id = fb.id
foobar_status = fb.status
foobar_data = fb.data
bar = foobar.bar
bar_id = fb.bar.id
bar_status = fb.bar.status
bar_data = fb.bar.data
fubar = ???
fubar_id = ???
fubar_status = ???
fubar_data = ???
Как получить доступ к отдельному объекту FuBar, связанному с каждой итерацией? В идеале я хотел бы иметь возможность получить его, не выполняя никаких дополнительных запросов в фоновом режиме, если это возможно.
Заранее спасибо.
--- редактировать ---
Я обновил описание проблемы выше, чтобы немного яснее понять точную природу проблемы. Я специально ищу отдельную конкретную запись FuBar
, связанную с каждой строкой набора результатов. Обратите внимание, что следующее:
foobar.bar.fubars
Это не то, что я хочу. Короче говоря, это возвращает набор FuBar
записей, относящихся к записи Bar
в строке текущего набора результатов. Он не говорит мне, какая конкретная запись была LEFT JOIN'd для текущей строки в наборе результатов.