Django скрывает весь раздел при отсутствии результата
В моем приложении Django есть строка поиска с функцией автозаполнения, которая отображает результаты на основе пользовательского ввода. Я подключил эту строку поиска к 3 моделям. Код ниже:
search_items.html
{% block body %}
<section class="py-3 model-1">
<h2>Model 1</h2>
<hr>
<div class="row">
{% for qa in qa_list %}
<div class="mb-3">{% include 'components/model_1_search.html' %}</div>
{% empty %}
<div class="align-items-center pt-4 mt-4">
<img class="img-fluid mx-auto d-block" src="{% static 'text no results.svg' %}">
</div>
{% endfor %}
</div>
</section>
<section class="py-3 model-2">
<h2>Model 2</h2>
<hr>
<div class="row">
{% for article in article_list %}
<div class="mb-3">{% include 'components/model_2_search.html' %}</div>
{% empty %}
<div class="align-items-center pt-4 mt-4">
<img class="img-fluid mx-auto d-block" src="{% static 'text no results.svg' %}">
</div>
{% endfor %}
</div>
</section>
<section class="py-3 model-3">
<h2>Model 3</h2>
<hr>
<div class="row">
{% for video in video_list %}
<div class="mb-3">{% include 'components/model_3_search.html' %}</div>
{% empty %}
<div class="align-items-center pt-4 mt-4">
<img class="img-fluid mx-auto d-block" src="{% static 'text no results.svg' %}">
</div>
{% endfor %}
</div>
</section>
<hr>
views.py
@login_required
def search_address_qa(request):
query = request.GET.get('title')
payload = []
if query:
lookups = Q(title__icontains=query)
address_objects = Article.objects.filter(lookups, status=1).distinct()
address_objects_qa = QA.objects.filter(lookups, status=1).distinct()
for address_object in address_objects or address_objects_qa:
payload.append(address_object.title)
return JsonResponse({'status':200, 'data': payload})
@login_required
def search_items(request):
query = request.GET.get('q')
modelone= ModelOne.objects.filter(title__icontains=query)
modeltwo= ModelTwo.objects.filter(title__icontains=query)
modelthree= ModelThree.objects.filter(title__icontains=query)
if query is not None:
lookups = Q(title__icontains=query) | Q(tags__name__icontains=query) | Q(short_description__icontains=query) | Q(body__icontains=query) | Q(category__title__icontains=query)
modelone = ModelOne.objects.filter(lookups).distinct()
modeltwo = ModelTwo.objects.filter(lookups).distinct()
modelthree= ModelThree.objects.filter(lookups, status=1).distinct()
context = {
'article_list': modelone,
'qa_list': modeltwo,
'video_list': modelthree,
}
return render(request, 'search/search_items.html', context)
Я не уверен, что это лучший способ сделать это, но я сейчас борюсь с отображением отсутствия результатов, потому что я хочу отобразить только один text no results.svg, если нет результатов в 3 моделях.
Более того, если объект найден только в Model 1, то я хочу скрыть Model 2 и Model 3. То же правило должно применяться к Model 2 и Model 3, поэтому если я нахожу объект только в Model 2, то разделы Model 1 и Model 2 должны исчезнуть
Просто оцените состояние игры и передайте его через контекст.
count1 = modelone.count()
count2 = modeltwo.count()
count3 = modelthree.count()
no_results = (count1 == 0 and count2 == 0 and count3 == 0)
context = {
'no_results' : no_results,
'article_list': modelone,
'qa_list': modeltwo,
'video_list': modelthree,
}
Другая часть вопроса сформулирована неправильно. Что значит найти объект только в модели 1, но не в модели 2? По определению это разные типы моделей, поэтому в каких терминах они считаются одинаковыми? Как только вы сможете выразить это в Python, оцените это перед рендерингом вашего шаблона, чтобы он мог легко выразить, что не рендерить в простых тестах if
{% if no_results %}
display no results.svg
{% else %}
...
{% endif %}
Другие вещи, которые могут помочь. Вы можете отобразить пустой кверисет с помощью queryset.none() (так что шаблон, который итерирует над ним {% for x in queryset %}, итерирует ноль раз и отображает часть {% empty %}, если она присутствует.
Вы можете просто сделать прямой рендеринг в шаблоне вместо того, чтобы вычислять так много вещей. Вы можете сделать это следующим образом:
{% if article_list %}
show result here
{% else %}
display no results.svg
{% endif %}
{% if qa_list %}
show result here
{% else %}
display no results.svg
{% endif %}
{% if video_list %}
show result here
{% else %}
display no results.svg
{% endif %}
Тег if будет оцениваться как false, если он пуст. Это уменьшит вычисления .count() и отправку большего количества переменных.