#django #django-queryset
Вопрос:
После обновления с Django 1.9 до 3.2.5 моя функция расширенного поиска больше не работает с разбиением на страницы.
У меня есть две функции поиска. Тот, который всегда доступен в заголовке для поиска названий проектов и включен в мой base.html шаблон. Другая-это функция расширенного поиска, которая позволяет выполнять поиск по определенным критериям, например, отделу, названию проекта, статусу и т.д.
все работает нормально, пока нет разбивки на страницы. обычная функция поиска работает с разбиением на страницы, но расширенная-нет.
Проблема, по-видимому, заключается в возврате запроса, который возвращает один список для разных запросов, начинающихся с q=[«,»,»]. Потому что поля моей формы в расширенном поиске имеют разные имена,например, qD, qS и т.д. части списка не могут быть правильно назначены.
возврат URL-адреса при выполнении расширенного поиска перед сменой страницы:
http://127.0.0.1:8000/advanced_search/?csrfmiddlewaretoken=rzIvrOJdUMHwwxaSR18hy48mPTNCORXjaMYigqELXKRlKzNhBpEjbVSueQGHs7ylamp;qD=corporateamp;qC=amp;qN=amp;qT=amp;qS=amp;qA=amp;qCD=
возврат URL-адреса при выполнении расширенного поиска после смены страницы:
http://127.0.0.1:8000/advanced_search/?page=2amp;q=(None, 'corporate', '', '', '', '', '', '')
вот мой django и html-код:
views.py
# normal search
def search(request):
template = 'MAR_Projects/projects.html'
query = request.GET.get('q')
if query:
filtered_projects = table_projects.objects.filter(Q(Project_Code__icontains=query) | Q(Project_Name__icontains=query))
else:
filtered_projects = table_projects.objects.all().order_by('-Project_Creation')
searchResultCount = filtered_projects.count
pages = pagination(request, filtered_projects)
context = {'items': pages[0],
'page_range': pages[1],
'query': query,
'searchResultCount':searchResultCount
}
return render(request, template, context)
#advanced search
def advanced_search(request):
template = 'MAR_Projects/advanced_search.html'
filtered_projects = table_projects.objects.all()
query = (request.GET.get('q'),request.GET.get('qD'), request.GET.get('qC'), request.GET.get('qN'), request.GET.get('qT'), request.GET.get('qS'), request.GET.get('qA'),
request.GET.get('qCD'))
result = False
for i,q in enumerate(query):
if q and i== 1:
filtered_projects = filtered_projects.filter(Q(Project_Department_id__BUs_Code__icontains = query[i]))
result = True
elif q and i== 2:
filtered_projects = filtered_projects.filter(Q(Project_Code__icontains = query[i]))
result = True
elif q and i== 3:
filtered_projects = filtered_projects.filter(Q(Project_Name__icontains = query[i]))
result = True
elif q and i== 4:
filtered_projects = filtered_projects.filter(Q(Project_Type_id__ProjectType_Code__icontains = query[i]))
result = True
elif q and i== 5:
filtered_projects = filtered_projects.filter(Q(Project_Status_id__ProjectStatus_code__icontains = query[i]))
result = True
elif q and i== 6:
filtered_projects = filtered_projects.filter(Q(Project_Assignee_id__Assignee_Name__icontains = query[i]))
result = True
elif q and i== 7:
filtered_projects = filtered_projects.filter(Q(Project_Creation__icontains = query[i]))
result = True
searchResultCount = filtered_projects.count
pages = pagination(request, filtered_projects)
context = {'items': pages[0],
'page_range': pages[1],
'result': result,
'query': query,
'searchResultCount':searchResultCount,
}
return render(request, template, context)
advanced_search.html шаблон
{% extends 'Mar_Projects/base.html' %}
{% load static %}
{% block content %}
{% if user.is_authenticated %}
<h4>Advanced search</h4>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">BUs</th>
<th scope="col">Project Code</th>
<th scope="col">Name</th>
<th scope="col">Type</th>
<th scope="col">Status</th>
<!-- <th scope="col-sm">Description</th>-->
<th scope="col">Assignee</th>
<th scope="col">Creation Date</th>
</tr>
</thead>
<tbody>
<tr>
<form method="get" action={% url 'MAR_Projects:advanced_search' %}>
{% csrf_token %}
<th scope="row"></th>
<td><input class="form-control mr-sm-2" type="search" placeholder="Department" aria-label="Department" name='qD' value= {{ request.GET.qD}}></td>
<td><input class="form-control mr-sm-2" type="search" placeholder="Code" aria-label="Code" name='qC' value= {{ request.GET.qC}}></td>
<td><input class="form-control mr-sm-2" type="search" placeholder="Name" aria-label="Name" name='qN' value= {{ request.GET.qN}}></td>
<td><input class="form-control mr-sm-2" type="search" placeholder="Type" aria-label="Type" name='qT' value= {{ request.GET.qT}}></td>
<td><input class="form-control mr-sm-2" type="search" placeholder="Status" aria-label="Status" name='qS' value= {{ request.GET.qS}}></td>
<td><input class="form-control mr-sm-2" type="search" placeholder="Assignee" aria-label="Assignee" name='qA' value= {{ request.GET.qA}}></td>
<td><input class="form-control mr-sm-2" type="search" placeholder="Date" aria-label="Date" name='qCD' value= {{ request.GET.qCD}}></td>
</tr>
<tr><td></td><td>{%if result %}{{searchResultCount}} Found{% endif %}</td><td></td><td></td><td></td><td></td><td></td>
<td><input type="submit" class="btn btn-secondary" value="Search"></td>
</tr>
</form>
{%if result %}
{%for pj in items%}
<tr>
<th scope="row">{{ forloop.counter0 | add:items.start_index }}</th>
<td>{{pj.Project_Department}}</td>
<td><a href = '/projects/{{pj.Project_Id}}'>{{pj.Project_Code}}</a></td>
<td>{{pj.Project_Name}}</td>
<td>{{pj.Project_Type}}</td>
<td>{{pj.Project_Status}}</td>
<!--<td style="max-width:350px;white-space:nowrap; overflow:hidden">{{pj.Project_Description}}</td>
-->
<td>{{pj.Project_Assignee}}</td>
<td>{{pj.Project_Creation}}</td>
</tr>
{%endfor%}
{% endif %}
</tbody>
</table>
<br/>
{%if result %}
{% include 'MAR_Projects/pagination.html' %}
{% endif %}
{% endif %}
{% endblock %}
base.html шаблон
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/open-iconic/1.1.1/font/css/open-iconic-bootstrap.min.css" integrity="sha256-BJ/G e y7bQdrYkS2RBTyNfBHpA9IuGaPmf9htub5MQ=" crossorigin="anonymous" />
<title>{% block title%}Project{%endblock%}</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
{% if user.is_authenticated %}
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{%url 'MAR_Projects:home' %}">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="{%url 'MAR_Projects:projects' %}">Projects Overview</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'MAR_Projects:projectCreate' %}">
<span class="oi oi-plus" aria-hidden="true"></span>amp;nbsp; Project
</a>
</li>
</ul>
<ul class="navbar-nav">
<li>
<form class="form-inline my-2 my-lg-0" method="GET" action = {% url 'MAR_Projects:search-results' %}>
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name='q' value= {{ request.GET.q}}>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</li>
<li class="nav-item">
<a class="btn btn-outline-success my-2 my-sm-0" href="{%url 'MAR_Projects:advanced_search' %}">Adv. Search</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ user }}</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/profile">Profile</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/logout">Logout</a>
</div>
</li>
</ul>
</div>
{% else %}
<ul class="navbar-nav navbar-right">
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</li>
</ul>
{% endif %}
</nav>
<br/>
<div class="container-fluid">
{% if messages %}
<div class="span12">
{% for message in messages %}
<div class="alert alert-{{ message.level_tag }}" role="alert">
{{ message|safe }}
</div>
{% endfor %}
</div>
{% endif %}
{% block content %}
{% endblock %}
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X 965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH 8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV 2 9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3 MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
</body>
</html>
Ответ №1:
мне потребовалось некоторое время, но я сам отвечаю на свой вопрос.
возможно, это не лучшее решение, но оно работает.
В views.py:
query = (request.GET.get('q'),request.GET.get('qD'), request.GET.get('qC'), request.GET.get('qN'), request.GET.get('qT'), request.GET.get('qS'), request.GET.get('qA'),
request.GET.get('qCD'))
qDic = {'q':query[0],'qD':query[1],'qC':query[2],'qN':query[3],'qT':query[4],'qS':query[5],'qA':query[6],'qCD':query[7]}
searchResultCount = filtered_projects.count
pages = pagination(request, filtered_projects)
context = {'items': pages[0],
'page_range': pages[1],
'result': result,
'query': qDic,
'searchResultCount':searchResultCount,
}
return render(request, template, context)
Я создал словарь qDic и вставил результаты своего запроса.
В моем pagination.html шаблон:
{% if items.has_other_pages %}
<div class="col-6 offset-3 text-center pagination-set">
<nav aria-label="">
<ul class="pagination justify-content-end">
{% if items.has_previous %}
<li class="page-item"><a class="page-link" href="?page={{ items.previous_page_number }} {% if query %}amp;qD={{ query.qD }}amp;qC={{ query.qC }}amp;qN={{ query.qN }}amp;qT={{ query.qT }}amp;qS={{ query.qS }}amp;qA={{ query.qA }}amp;qCD={{ query.qCD }}{%endif%}">amp;laquo;</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link"><span>amp;laquo;</span></a></li>
{% endif %}
{% for i in page_range %}
{% if items.number == i %}
<li class="page-item active"><a class="page-link" href="#">{{ i }} <span class="sr-only">(current)</span></a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ i }}{% if query %}amp;qD={{ query.qD }}amp;qC={{ query.qC }}amp;qN={{ query.qN }}amp;qT={{ query.qT }}amp;qS={{ query.qS }}amp;qA={{ query.qA }}amp;qCD={{ query.qCD }}{%endif%}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if items.has_next %}
<li class="page-item"><a class="page-link" aria-label="Next" href="?page={{ items.next_page_number }}{% if query %}amp;qD={{ query.qD }}amp;qC={{ query.qC }}amp;qN={{ query.qN }}amp;qT={{ query.qT }}amp;qS={{ query.qS }}amp;qA={{ query.qA }}amp;qCD={{ query.qCD }}{%endif%}">amp;raquo;</a></li>
{% else %}
<li class="page-item disabled"><a class="page-link"><span>amp;raquo;</span></a></li>
{% endif %}
</ul>
</nav>
</div>{% endif %}
Я передал запрошенные словарные статьи в соответствующие поля запроса в своем advanced_search.html шаблон.
надеюсь, в этом есть смысл.
лучшие решения всегда приветствуются.