如何使分页与过滤 django 一起使用?

Posted

技术标签:

【中文标题】如何使分页与过滤 django 一起使用?【英文标题】:How can I make pagination to work with filtering django? 【发布时间】:2021-12-29 21:07:28 【问题描述】:

我有一个分页的网页,但是当我点击第二个按钮时,我的数据库中的所有数据都会出现,我只想根据我设置的过滤器进行分页,就像技术调查只会出现状态为技术调查。

升序排序是有效的,但是当我点击零件编号或其他 3 个时,它也会显示数据库中的所有数据,如何防止这种情况并仅显示过滤的数据库下一个状态?

这是我当前的页面,但是当我点击数字 2 时,所有数据都会出现,我对下一个状态技术调查的过滤将不再起作用。

views.py

@login_required()
def investigation(request):
    search_post = request.GET.get('q')
    # Code for the users to search for reception, partno, serialno, mconum, customername
    if (search_post is not None) and search_post:
        allusername = Photo.objects.filter(Q(reception__icontains=search_post) | Q(partno__icontains=search_post) | Q(
            Customername__icontains=search_post) | Q(mcoNum__icontains=search_post) | Q(
            serialno__icontains=search_post))
        if not allusername:
            allusername = Photo.objects.all().order_by("-Datetime")


    else:
        allusername = Photo.objects.all().filter(Q(nextstatus='Technical Investigation')).order_by("-Datetime")

    # Sort BY:
    part = request.GET.get('sortType')
    valid_sort = ["partno", "serialno", "Customername", "mcoNum"]  # Sort the workshop data in ascending order acording to the part number, serial number, customer name and the MCO Number
    if (part is not None) and part in valid_sort:
        allusername = allusername.order_by(part)

    page = request.GET.get('page')
    paginator = Paginator(allusername, 10)  # 1 page will only show 10 data, if more than 10 data it will move it to the next page.
    try:
        allusername = paginator.page(page)
    except PageNotAnInteger:
        allusername = paginator.page(1)
    except EmptyPage:
        allusername = paginator.page(paginator.num_pages)

    context = 'allusername': allusername, 'query': search_post, 'order_by': part
    return render(request, 'workshop/investigation.html', context)

调查.html

     % extends "workshop/workshopbase.html" %
    % block content %
      <meta http-equiv="refresh" content="60">

    <style>
    table 
        border-collapse:separate;
        border:solid black 1px;
        border-radius:6px;
        -moz-border-radius:6px;
    

    td, th 
        border-left:solid black 1px;
        border-top:solid black 1px;
    

    th 
        border-top: none;
    

    td:first-child, th:first-child 
         border-left: none;
    

   ul.pagination li a 
    display: block;
    padding: 5px 15px;


ul.pagination li.active 
    padding: 5px 15px;
    background-color: hsla(199, 34%, 55%, 1);
    border-radius: 30px;
    color: white;


ul.pagination li.disabled 
    padding: 5px 15px;


ul.pagination li 
    display: block;
    //border: 1px solid hsla(199, 34%, 64%, 0.74);


ul.pagination li a:hover,
ul.pagination li a:active 
    border-radius: 30px;
    background-color: hsla(199, 34%, 64%, 0.74);

@media only screen and (min-width: 268px) 
    ul.pagination 
        display: flex;
        justify-content: left;
        align-items: right;
        font-size: 18px;
    
    .sort 
    display: inline;
    margin: 0 15px 0 20px;
    


    </style>
    <script>


     // Function to download table data into csv file
            function download_table_as_csv(table_id, separator = ',') 
                var rows = document.querySelectorAll('table#' + table_id + ' tr');
                var csv = [];
                for (var i = 0; i < rows.length; i++) 
                    var row = [], cols = rows[i].querySelectorAll('td, th');
                    for (var j = 0; j < cols.length; j++) 
                        var data = cols[j].innerText.replace(/(\r\n|\n|\r)/gm, '').replace(/(\s\s)/gm, ' ')
                        data = data.replace(/"/g, '""');
                        row.push('"' + data + '"');
                    
                    csv.push(row.join(separator));
                
                var csv_string = csv.join('\n');
                var filename = 'export_' + table_id + '_' + new Date().toLocaleDateString() + '.csv';
                var link = document.createElement('a');
                link.style.display = 'none';
                link.setAttribute('target', '_blank');
                link.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv_string));
                link.setAttribute('download', filename);
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            ;


             if (urlParams.has('sortType')) 
                var checked = urlParams.get('sortType')
                $(`#$checked`).prop("checked", true);
            
            else 
                $(`#current_log`).prop("checked", true);
            ;

             //Whenever sortType checkboxes is selected/unselected, add it to the url or remove it
            );
            $("input[name='sortType']").change(function () 
                var selected = $('input[name="sortType"]:checked').val();
                changeParams('sortType', selected)

            );

    </script>


       <div style="padding-left:16px">
         <br>

     <div class="form-block">
         <h6>Search for Part Number/ Serial Number/ Reception Number/ MCO Number/ Customer Name</h6>
        <form class="form-inline my-2 my-lg-0" action="% url 'investigation' %" method='GET' value=' request.GET.q '>
            <input class="form-control mr-sm-2" type="text" 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>
        <div class="sort">
           <h5 class="col-md-3">Sort By : </h5>


                <div id="sortBlock" class="col-md-9">
                    <form class="form-inline my-2 my-lg-0" action="" method='GET' value=' request.GET.sortType '>

                    <div class="sort">
                        <input type="radio" id="partno" name="sortType" value="partno">
                        <label for="partno">Part Number</label>
                    </div>

                     <div class="sort">
                        <input type="radio" id="serialno" name="sortType" value="serialno">
                        <label for="serialno">Serial Number</label>
                    </div>

                         <div class="sort">
                        <input type="radio" id="mcoNum" name="sortType" value="mcoNum">
                        <label for="mcoNum">MCO Number</label>
                        </div>

                    <div class="sort">
                        <input type="radio" id="Customername" name="sortType" value="Customername">
                        <label for="Customername">Customer Name</label>
                    </div>

                         <div class="sort">
                        <input type="Submit" value="Sort"/>
                    </div>
                    </form>
                </div>
         </div>

         <br>
       <table id="viewTable" class="m-2">
            <i class="fa fa-download" aria-hidden="true"></i>
                <a href="#" onclick="download_table_as_csv('viewTable');">Download as CSV</a>
           <br>

      <tr class="header">
        <th>Latest Log</th>
          <th>Part Number</th>
          <th>Serial Number</th>
          <th>Reception Number</th>
          <th>MCO Number</th>
          <th>Customer Name</th>
          <th>Current Status</th>
          <th>Next Status</th>
          <th>Action</th>
      </tr>
             % for photo in allusername %

      <tr>
          <td>photo.Datetime</td>
          <td>photo.partno</td>
          <td>photo.serialno</td>
          <td>photo.reception</td>
          <td>photo.mcoNum</td>
          <td>photo.Customername</td>
          <td>photo.status</td>
          <td>photo.nextstatus</td>
          <td>
              <form action="% url 'investigationdetails' photo.id %" method="post">
              % csrf_token %
          <button type="submit" class="btn btn-sm btn-info">View</button>
      </form>
          </td>

      </tr>

    % endfor %

    </table>



  % if allusername.has_other_pages %

  <ul class="pagination pr-3 mr-1 ml-auto">

    % if allusername.has_previous %
      <li><a href="?q= query|urlencode &sortType= order_by &page= allusername.previous_page_number ">&laquo;</a></li>
    % else %
      <li class="disabled"><span>&laquo;</span></li>
    % endif %
    % for i in allusername.paginator.page_range %
      % if allusername.number == i %
        <li class="active"><span> i  <span class="sr-only">(current)</span></span></li>
      % else %
        <li><a href="?q= query|urlencode &sortType= order_by &page= i "> i </a></li>
      % endif %
    % endfor %
    % if allusername.has_next %
      <li><a href="?q= query|urlencode &sortType= order_by &page= allusername.next_page_number ">&raquo;</a></li>
    % else %
      <li class="disabled"><span>&raquo;</span></li>
    % endif %
    </ul>
    % endif %

     </div>
    </div>

% endblock %

【问题讨论】:

我需要分页、过滤下一个状态和排序依据才能工作 【参考方案1】:

问题出在你的views.py中。你可以在尝试所有其他逻辑和排序之后调用Padignator之前调用 allusername = allusername.filter(Q(nextstatus__icontains='Technical Investigation'))

@login_required()
def investigation(request):
    search_post = request.GET.get('q')
    # Code for the users to search for reception, partno, serialno, mconum, customername
    if (search_post is not None) and search_post:
        allusername = Photo.objects.filter(Q(reception__icontains=search_post) | Q(partno__icontains=search_post) | Q(
            Customername__icontains=search_post) | Q(mcoNum__icontains=search_post) | Q(
            serialno__icontains=search_post))
        if not allusername:
            allusername = Photo.objects.all().order_by("-Datetime")


    else:
        allusername = Photo.objects.all().order_by("-Datetime")

    # Sort BY:
    part = request.GET.get('sortType')
    valid_sort = ["partno", "serialno", "Customername", "mcoNum"]  # Sort the workshop data in ascending order acording to the part number, serial number, customer name and the MCO Number
    if (part is not None) and part in valid_sort:
        allusername = allusername.order_by(part)

    page = request.GET.get('page')
    allusername = allusername.filter(Q(nextstatus__icontains='Technical Investigation')) # new
    paginator = Paginator(allusername, 10)  # 1 page will only show 10 data, if more than 10 data it will move it to the next page.
    try:
        allusername = paginator.page(page)
    except PageNotAnInteger:
        allusername = paginator.page(1)
    except EmptyPage:
        allusername = paginator.page(paginator.num_pages)

    context = 'allusername': allusername, 'query': search_post, 'order_by': part
    return render(request, 'workshop/investigation.html', context)

【讨论】:

以上是关于如何使分页与过滤 django 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

Python入门自学进阶-Web框架——25DjangoAdmin项目应用-分页与过滤

Python入门自学进阶-Web框架——25DjangoAdmin项目应用-分页与过滤

django-filter 使用分页

如何在 ExtJS 中动态更改分页网址?

当我在基于类的视图中应用过滤器时,如何在 django 中使用分页分页。网址总是不断变化我如何跟踪网址

如何使用 Django Rest Framework 过滤器将过滤器链接在一起