У меня есть представление в моем проекте 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 опций (что является несколько плохим дизайном интерфейса/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 вариантам. Может быть, мне следует использовать другой компонент вместо списка данных?
Если да, то зачем вам все 1000? Какой пользователь прочитает все 1000? Это плохой дизайн, очень плохой дизайн. Научитесь использовать отладчик, чтобы знать, что именно происходит с вашим кодом и где могут быть узкие места. Кроме того, чтобы ваш браузер отображал 1000 вариантов выбора, потребуются некоторые вычислительные усилия.