简体   繁体   中英

Prefetch_related and number of generated queries

I have two models:

class Folder(AbstractName):

    parent = models.ForeignKey('self', blank=True, null=True)
    owner = models.ForeignKey(User)
    typeof = models.ForeignKey(TypeParent, blank=True, null=True)

class File(AbstractName):

    folder = models.ForeignKey(Folder, blank=True, null=True)
    owner = models.ForeignKey(User)
    typeof = models.ForeignKey(TypeChild)

And my folder list (which should display File & folder children, like the explorer file.) generates many queries.

class FolderList(ListView, LoginRequiredView):
    model = Folder

    def get_queryset(self):
        return Folder.objects.filter(owner=self.request.user, parent=None).prefetch_related('folder_set').prefetch_related('file_set')

In my template:

#folder_list 
{% include 'core/_folders.html' %}

#_folders
{% if object_list %}
{% for object in object_list %}
    <li><a href="{% url 'folder_detail' object.pk %}">{{ object.name }}</a></li>
    <ul>
        {% for file in object.file_set.all %}
            <li><i>{{ file }}</i></li>
        {% endfor %}

        {% with filename='core/_folders.html' %}
            {% with object_list=object.folder_set.all %}
                {% include filename %}
            {% endwith %}
        {% endwith %}

    </ul>
{% endfor %}
</ul>
{% endif %}

First step: Install django-debug-toolbar so you can see where the queries are being triggered.

Next step: Understand how prefetch_related and select_related work. In a nutshell, select_related does a JOIN query to fetch single ForeignKey models and include them in the results. This gives a slightly longer executing query but is much faster if you're iterating over many items. prefetch_related will work for M2M fields and does the JOIN work in Python code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM