Django - Отображение списка пользователей занимает более 14 секунд, как его ускорить? - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть представление, в котором будут отображаться элементы на основе выбранной буквы (например, при нажатии L на веб-странице отобразятся все элементы, чье имя начинается с L, упорядоченное по фамилии)

Проблема в том, что для отображения страницы может потребоваться более 14 секунд (например, «M», около 180 участников в списке, 17 секунд или около того). SQL-запрос не выглядит проблемой, так как панель инструментов отладки сообщает, что для выполнения запроса требуется менее секунды.

Вот вид:

def show_all_members(request, letter):
    members = MyUsers.objects.filter(firstname__istartswith=letter).order_by('lastname')
    alphabet = list(string.ascii_lowercase)
    request.session['url'] = request.get_full_path()
    context_dict = {'all_members': members, 'alphabet': alphabet}
    return render(request, "users/show_all_members.html", context_dict)

Программирование - это хобби, поэтому я немного растерялся, что здесь происходит и как его оптимизировать. Любая помощь и указатель приветствуется.

Использование Django 2.1.1

Редактировать: вот шаблон. Показывает, купил ли участник перфокарты или пропуска, а также ссылку на его профиль.

{% extends "base.html" %}
{% load staticfiles %}
{% load i18n %}
{% block title %}Members{% endblock %}

{% block content %}

<div class="container">
  <div class="page-header" xmlns="http://www.w3.org/1999/html">
    <h2>Tribe members list</h2>

    {% for l in alphabet %}
      <a href="{% url 'users:show_all_members' l %}" class="btn btn-success"> 
        {{ l }}

      </a>
    {% endfor %}
   
  </div>
  <br>

  {% for user in all_members %}


    <div class="row"> 
    <p>
      <div class="col-md-2">
          <a href="{% url 'users:member_info' user.id %}" >
            <h7>{{ user.fullname  }}</h7>
          </a>
      </div>
      <div class="col-md-1">
          <a class="btn btn-warning btn-sm" href="{% url 'users:edit_profile_full' user.id %}"> Edit Profile</a>
      </div>
      <div class="col-md-6">
          <a class="btn btn-success btn-sm" href="{% url 'classes:buy_pass' user.id  %}"> Current PC/SP</a>
          {%if user.punchcardbyuser_set.all %}
            {%for pc in user.punchcardbyuser_set.all %}
            <span class="badge badge-primary" >{{ pc.cardclasstype.name }}:{{ pc.classes }}</span>
            {%endfor%}           
          {% endif %}

          {%if user.allaccesspassbyuser_set.all %}
          {%for aap in user.allaccesspassbyuser_set.all %}
          <span class="badge badge-danger">AAP:{{ aap.classes }}</span>
          {%endfor%}           
        {% endif %}
        
        {%if user.seasonpass_set.all %}
        /
          {%for sp in user.seasonpass_set.all %}
            <span class="badge badge-primary">{{ sp.label }}</span>
          {%endfor%}
        {% endif %}
      </div>
      <div class="col-md-3">
          <a class="btn btn-success btn-sm" href="{% url 'classes:buy_pass' user.id  %}"> Buy passes</a>

     
           <a class="btn btn-primary btn-sm" href="{% url 'users:detail' user.username %}">Class attended: {{user.classes_set.all|length}}</a>

      </div>
    </p>
    </div>

  {% endfor %}
  
</div>
{% endblock content %}

1 Ответ

0 голосов
/ 17 сентября 2018

Благодаря советам @Willem Van Onsem я прочитал о Django N + 1, и это действительно было проблемой.Всего у меня было 747 запросов ... (!) (Страница отображает много информации из разных отношений M2M.) Если прочитать «prefetch_related» и некоторые неудобства, то теперь она опустилась до 7, а страница теперь загружается за 1,2 секунды.Максимум.Я уверен, что смогу снизить его, узнав больше об оптимизации запросов.

members = MyUsers.objects.filter(firstname__istartswith=letter).order_by('lastname').prefetch_related("punchcardbyuser_set").prefetch_related("classes_set").\
                                prefetch_related("allaccesspassbyuser_set").prefetch_related("seasonpass_set")

Спасибо!

...