Django listview не использует операторы join sql для внешнего ключа

Я новичок в Django и все еще изучаю основы. Я играл с общим ListView, и меня смущают запросы sql, стоящие за генерацией содержимого списка. Вот простой пример для иллюстрации:

Моя модель:

class Member(models.Model):
    def __str__(self):
        return self.name

    name = models.CharField()

class Phone(models.Model):
    phone = models.CharField()
    member = models.ForeignKey(Member)

Мои взгляды:

from django.views.generic import ListView
class PhoneList(ListView):
    models=Phone

Мой шаблон:

{% for obj in object_list %}
    <tr><td>{{ obj.member }}</td><td>{{ obj.phone }}</td><td></tr>
{% endfor %}

Теперь предположим, что я поместил несколько записей в таблицу Phone:

1 - member_id=1, phone='123425'  
2 - member_id=2, phone='234234'  
3 - member_id=5, phone='9043234'
...

Итак, я запускаю этот ListView, и все отображается, как ожидалось. Номера телефонов указаны рядом с именами участников.

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

Это кажется очень неэффективным. Если я возьму 1000 телефонных записей, он выполнит 1000 запросов в базу данных? Почему не используется запрос JOIN? Я, должно быть, что-то упускаю. Кстати, я использую MySQL в качестве базы данных.

Вам нужен select_related().

Daniel Roseman 11.04.2018 13:55

Может ли здесь происходить кеширование запросов sql, так что Django на самом деле не попадает в базу данных несколько раз?

user3628119 11.04.2018 13:56

@ Даниэль: Хорошо, спасибо. Позвольте мне разобраться в этом.

user3628119 11.04.2018 13:57

Да это оно. Мне нужно добавить queryset = Phone.objects.select_related() в PhoneList. Спасибо!

user3628119 11.04.2018 14:08
0
4
262
0

Другие вопросы по теме