Django — несколько запросов с разбиением на страницы

#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 шаблон.

надеюсь, в этом есть смысл.

лучшие решения всегда приветствуются.