Как получить данные из нескольких моделей в наборе запросов, используя select_related?

Я пытаюсь получить комбинированный набор запросов для двух моделей, в основном LEFT JOIN для двух таблиц.

Я прочитал несколько ответов о том, как выполнить LEFT JOIN для наборов запросов, и обнаружил, что проще всего использовать select_related, что я и сделал.

Когда я печатаю необработанный запрос, он выглядит хорошо, он содержит информацию из обеих таблиц (обе модели).

Однако возвращенный набор запросов содержит только информацию из первой модели. Я читал, что это значение по умолчанию, и его можно переопределить с помощью get_query. И здесь я теряюсь, потому что в документации есть описание get_query только для представления на основе классов, а до сих пор я работал только с представлениями на основе функций.

Это мои модели:

    class WorkPlace(models.Model):
        workplace   = models.TextField(unique=True)
        nickname    = models.TextField(null=True)

        def __str__(self):
            return f'{self.workplace}'

    class Status(models.Model):
        workplace   = models.OneToOneField(WorkPlace, to_field="workplace", db_column="workplace", on_delete=models.SET_NULL, null=True)
        status      = models.TextField()

        def __str__(self):
            return f'{self.status}'

Это вид:

    def work_place_list_view(request):
        qs1 = WorkPlace.objects.select_related('status')
        print(qs1.query)
        context = {"workplace_list": qs1, "title": "Seznam pracovišť"}
        template_name = 'megavisor/workplace_list.html'
        return render(request, template_name, context) 

Это необработанный запрос из консоли:

SELECT "megavisor_workplace"."id", "megavisor_workplace"."workplace", "megavisor_workplace"."nickname", "megavisor_status"."id", "megavisor_status"."workplace", "megavisor_status"."status" FROM "megavisor_workplace" LEFT OUTER JOIN "megavisor_status" ON ("megavisor_workplace"."workplace" = "megavisor_status"."workplace")

Выходом является набор запросов, содержащий только информацию из модели класса WorkPlace. Мне нужно, чтобы он содержал также информацию из модели класса WorkPlaceStatus.


person Peter Vajda    schedule 01.08.2019    source источник


Ответы (1)


Добавить родственное имя на рабочем месте.

 workplace   = models.OneToOneField(WorkPlace,  related_name="work", to_field="workplace", db_column="workplace", on_delete=models.SET_NULL, null=True)

затем используйте этот запрос,

qs1 = WorkPlace.objects.select_related('work')

и вы не можете использовать status в select_related, потому что ваш внешний ключ был workplace.

person sandeep    schedule 01.08.2019
comment
Работающий! Спасибо, related_name сделал свое дело, хотя раньше я помещал его не в то место. - person Peter Vajda; 01.08.2019