Реализация LEFT JOIN явно в Django - PullRequest
1 голос
/ 03 октября 2019

Я был бесконечным сообщениями о Django и проблеме LEFT JOIN, но я не нашел ни одного, кто имеет решение в версии Django 2.2. Хотя в прошлые годы казалось, что были способы обойти эту проблему, команда Django, похоже, отключила все механизмы, которые люди использовали для достижения самого простого, но необходимого запроса - LEFT JOIN. Вот пример примера того, что я пытаюсь сделать (это простой пример для отражения сценария реального мира, поэтому, пожалуйста, не предлагайте способы перепроектировать модели ... всеЯ хочу, чтобы это был старый LEFT JOIN в SQL .... это просто):

from django.db import models
from uuid import uuid4
class People(models.Model):
    id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
    name = models.CharField(max_length=255)


class Book(models.Model):
    id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
    name = models.CharField(max_length=255)
    author = models.ForeignKey(People)
    publisher = models.ForeignKey(People, on_delete=models.PROTECT, null=True)

Как бы получить вывод, показывающий все книги и издателя , если естьявляется издателем (в противном случае просто пустым)

Books.objects.filter(Q(publisher__isnull=True | Q(publisher__isnull=False)

... создает ВНУТРЕННЕЕ СОЕДИНЕНИЕ, которое, очевидно, будет показывать только книги, для которых назначен издатель. Запрос, который я ищу, будет иметь следующий вид: выберите * из книги ВЛЕВО ПРИСОЕДИНЯЙТЕСЬ к людям НА book.publisher_id = people.id

... или я должен прибегнуть к необработанному SQL для этого наиболее простого изтребования

1 Ответ

1 голос
/ 03 октября 2019

Вы можете выполнить .select_related(..) [Django-doc] здесь:

Book.objects.select_related('publisher')

Это приведет к получению как данных Book, так и связанных с нимиPublisher, если он существует. Так что some_book.publisher, где some_book происходит из этого набора запросов, не приведет к дополнительному запросу для выборки издателя. Запрос будет выглядеть так:

SELECT book.id, book.name, book.author_id, book.publisher_id,
       people.id, people.name
FROM book
LEFT OUTER JOIN people ON book.publisher_id = people.id
...