Представление Django работает медленно

У меня есть представление в моем проекте Django:

@permission_required('storage.add_iteminrelease')
@transaction.atomic
def add_item_in_release(request, id):
    release = get_object_or_404(Release, pk=id)
    if (request.method == 'POST'):
        add_item_in_release_form = ItemInReleaseForm(request.POST)
        if add_item_in_release_form.is_valid():
            add_item_in_release_form.instance.release = release
            item = add_item_in_release_form.cleaned_data['item']
            if item.count < add_item_in_release_form.cleaned_data['count']:
                messages.add_message(request,
                                     messages.ERROR,
                                     'Кол-во выдачи не должно превышать ' + str(item.count))
                return redirect('/releases/details/' + str(id) + '/')
            item.count -= add_item_in_release_form.cleaned_data['count']
            item.save()
            item_in_release, create = ItemInRelease.objects.get_or_create(item=add_item_in_release_form.cleaned_data['item'],
                                                                          release=release,
                                                                          defaults = {'count': add_item_in_release_form.cleaned_data['count']})
            if not create:
                item_in_release.count += add_item_in_release_form.cleaned_data['count']
            item_in_release.save()
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Позиция успешно добавлена')
            return redirect('/releases/details/' + str(id) + '/')
        messages.add_message(request,
                 messages.ERROR,
                 add_item_in_release_form.errors.as_data())
        return redirect('/releases/details/' + str(id) + '/')
    else:
        add_item_in_release_form = ItemInReleaseForm()
    return render(request,
                    'add_item_in_release.html',
                    {'add_item_in_release_form': add_item_in_release_form,
                     'id': id})

и соответствующий шаблон html для этого шаблона, который загружается в модальное окно Bootstrap из другого шаблона:

<div class = "modal fade" id = "add-item" tabindex = "-1" aria-labelledby = "add-item-label" aria-hidden = "true"
  dats-bs-focus = "false">
  <div class = "modal-dialog">
    <div class = "modal-content">
      <div class = "modal-header">
        <h5 class = "modal-title" id = "add-item-label">Добавление позиции</h5>
        <button type = "button" class = "btn-close" data-bs-dismiss = "modal" aria-label = "Close"></button>
      </div>
      <form action = "{% url 'storage:add-item-in-release' id %}" method = "POST" class = "form" novalidate>
        <div class = "modal-body">
          {% csrf_token %}
          <div class = "form-floating w-100 mb-3">
            {{ add_item_in_release_form.contract }}
            <label for = "count">Договор</label>
          </div>
          <div class = "input-group flex-nowrap mb-3">
            <div class = "form-floating w-100">
              <input class = "form-control" id = "item-datalist" placeholder = "Позиция" name = "item"
                type = "text" list = "items" autocomplete = "off">
              <datalist id = "items">
                {% for i in add_item_in_release_form.fields.item.queryset %}
                  <option data-value = "{{ i.id }}" data-count = "{{ i.count }}" data-contract = "{{ i.contract }}" value = "{{ i.item.manufacturer.name }} {{ i.item.article }} {{ i.contract }}"></option>
                {% endfor %}
              </datalist>
              <label for = "item-datalist">Позиция</label>
            </div>
            <button class = "btn btn-outline-secondary" type = "button" id = "clear-input" title = "Очистить">
              <i class = "fa fa-eraser"></i>
            </button>
          </div>
          <div class = "input-group flex-nowrap mb-3">
            <div class = "form-floating w-100">
              {{ add_item_in_release_form.count }}
              <label for = "count">Кол-во</label>
            </div>
            <span class = "input-group-text w-25" id = "count-label" title = "Максимальное кол-во"></span>
          </div>
        </div>
        <div class = "modal-footer">
          <button type = "submit" class = "btn btn-outline-success">Добавить</button>
          <button type = "button" class = "btn btn-outline-primary" data-bs-dismiss = "modal">Отменить</button>
        </div>
      </form>
    </div>
  </div>
</div>

Когда я вызываю это представление, страница загружается до 10 секунд, но другие страницы загружаются мгновенно. Почему этот код такой медленный? Может быть, это потому, что у меня в списке данных около 1000 вариантов? Я не понимаю.

Если да, то зачем вам все 1000? Какой пользователь прочитает все 1000? Это плохой дизайн, очень плохой дизайн. Научитесь использовать отладчик, чтобы знать, что именно происходит с вашим кодом и где могут быть узкие места. Кроме того, чтобы ваш браузер отображал 1000 вариантов выбора, потребуются некоторые вычислительные усилия.

Chukwujiobi Canon 29.03.2024 14:04

Мне нужно перебрать все 1000 вариантов.

Sigarev Andrey 29.03.2024 14:32

Возможно, вам следует разбить его на другой компонент, где человек сможет искать. С точки зрения юзабилити прокручивать 1000 опций не очень приятно. Я бы сделал компонент, в котором вы можете ввести пару символов и который выдает запрос результата, который вы можете запросить через

gmv 03.04.2024 13:48

Я не могу разбить «элементы» экземпляра на разные компоненты, потому что человек ищет элементы, используя список данных, среди всех элементов, хранящихся на складе.

Sigarev Andrey 25.04.2024 10:55
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Код работает медленно не потому, что в списке 1000 опций (что является несколько плохим дизайном интерфейса/UI), а потому, что вы здесь так много запрашиваете ForeignKeys:

<datalist id = "items">
    {% for i in add_item_in_release_form.fields.item.queryset %}
        <option data-value = "{{ i.id }}" data-count = "{{ i.count }}" data-contract = "{{ i.contract }}" value = "{{ i.item.manufacturer.name }} {{ i.item.article }} {{ i.contract }}"></option>
    {% endfor %}
</datalist>

По сути, вам следует загрузить метод fields.item.queryset с именем select_releated и передать manufacturer и article. Не знаю, как это сделать в форме Django, но уверен, что это выполнимо. Возможно, вы могли бы попытаться переопределить магический подметод __init__, но это, вероятно, не лучший оптимальный способ (он будет быстрее, но запрос будет вызываться дважды, потому что для этого есть другой метод).

Ты прав. Я пытаюсь удалить список данных со всеми опциями, и страница начала загружаться мгновенно. Но мне нужна возможность поиска по всем 1000 вариантам. Может быть, мне следует использовать другой компонент вместо списка данных?

Sigarev Andrey 25.04.2024 10:58

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