【问题标题】:Pagination in filtered queryset using Django Listview使用 Django Listview 在过滤后的查询集中进行分页
【发布时间】:2022-01-26 02:38:56
【问题描述】:

在尝试过滤查询集时,我在通用 ListView 中使用分页时遇到问题。过滤器工作正常,但问题是当尝试访问不是第一个页面时,会出现错误:Invalid page (2): That page contains no results

如果我删除所有分页怎么办?你会推荐什么? 该模板的目标是在列表中显示日期过滤的销售额,同时也是一个客户过滤器

这是我的代码:

class ListSales(LoginRequiredMixin, ListView):
    template_name = "sales/list.html"
    context_object_name = 'sales'
    login_url = reverse_lazy('users_app:user-login')
    paginate_by = 5

    def get_queryset(self):
        client = self.request.GET.get("clientselect", "")
        date1 = self.request.GET.get("date1", '')
        date2 = self.request.GET.get("date2", '')

        if date1 == '':
            date1 = datetime.date.today()
        if date2 == '':
            date2 = datetime.date.today()
        queryset = Sale.objects.get_sales_list(date1, date2, client)
        return queryset

这是我的模板:

{% extends "panel.html" %}

{% load  static %}

{% block panel-content %}

<div class="grid-x medium-10">
    <h3 class="cell medium-12" style="text-align: center;">Ventas</h3> 
    <div class="cell medium-12">&nbsp </div>
    <form class="cell medium-10" method="GET">{% csrf_token %}
        <div class="input-group grid-x medium-12">
            
            <div class="input-group cell medium-3 grid-x">
                <label class="cell medium-12">Desde:</label>
                <span class="input-group-label"><i class="fi-calendar"></i></span>
                <input type="date" id="date1" name="date1" class="input-group-field" type="date">
                
            </div>
            &nbsp&nbsp&nbsp
            <div class="input-group cell medium-3 grid-x">
                <label class="cell medium-12">Hasta:</label>
                <span class="input-group-label"><i class="fi-calendar"></i></span>
                <input type="date" id="date2" name="date2" class="input-group-field" type="date">
                
            </div>
            <div class="cell medium-1"></div>
            <div class="input-group cell medium-3 grid-x">
                <label class="cell medium-12">Cliente:</label>
                <span class="input-group-label"><i class="fi-torso"></i></span>
                <select id="clientselect" name="clientselect" class="input-group-field">
                    <option value="0" id="option0" name="option0" >Todos</option>
                    <option value="-1" id="option-1" name="option-1" >Sin Cliente</option>
                    {% for client in clients %}
                    <option value="{{client.pk}}" id="option{{client.pk}}" name="option{{client.pk}}" >{{client.full_name}}</option>
                    {% endfor %}
                </select>
                
            </div>
            <div class="cell medium-1"></div>
            <div class="cell medium-1">
                <button type="submit" class="button cell medium-4"><i class="fi-filter"></i>&nbsp Filtrar</button>
            </div>
            
        </div>
    </form>
    <div class="cell medium-12"> </div>
    <table class="cell medium-12">
        <thead>
            <th>Fecha</th>
            <th>Nro Factura</th>
            <th>Cliente</a></th>            
            <th>Monto</th>
            <th>Acciones</th>
         
        </thead>
        <tbody>
          {% for sale in sales %}
            <tr>
                
              <td>{{ sale.show_date }}</td>
              <td>{{ sale.invoice_number }}</td>
              <td>{{ sale.client.full_name }}</td>
              <td>${{ sale.amount_with_discount}}</td>
              <td>
              <div class="button-group">
                <a href="#" class="button warning tiny" data-toggle="modalView{{sale.pk}}"><i class="fi-eye"></i></a>
                
            </td>
              </div>

            </tr>

        
            <div class="tiny reveal" id="modalView{{sale.pk}}" style="background-color:rgb(51,51,51);" data-reveal data-close-on-click="true" data-animation-in="spin-in" data-animation-out="spin-out">
                <h4 class="cell" style="text-align: center;">Detalle de Venta</h4>
    
                
              </div>


          {% endfor %}
        </tbody>
    </table>    

    {% if is_paginated %}
    <ul class="pagination cell medium-12">
      {% if page_obj.has_previous %}
      <li><a href="?page={{ page_obj.previous_page_number }}" style="color: wheat;">&laquo;</a></li>
      {% else %}
      <li class="disabled"><span style="color: wheat;">&laquo;</span></li>
      {% endif %} {% for i in paginator.page_range %} {% if page_obj.number == i %}
      <li class="active">
        <span style="color: wheat;">{{ i }} <span class="sr-only">(actual)</span></span>
      </li>
      {% else %}
      <li><a href="?page={{ i }}" style="color: wheat;">{{ i }}</a></li>
      {% endif %} {% endfor %} {% if page_obj.has_next %}
      <li><a href="?page={{ page_obj.next_page_number }}" style="color: wheat;">&raquo;</a></li>
      {% else %}
      <li class="disabled"><span style="color: wheat;">&raquo;</span></li>
      {% endif %}
    </ul>
    {% endif %}

  </div>

  
  
  {% endblock panel-content %}

【问题讨论】:

    标签: django django-models django-views django-templates django-pagination


    【解决方案1】:

    这个失败的原因是如果你点击下一页,剩下的查询字符串(搜索参数)没有传递给下面的请求。

    您可以使用以下代码对查询字符串的其余部分进行编码:

    class ListSales(LoginRequiredMixin, ListView):
        # …
        
        def urencode_filter(self):
            qd = self.request.GET.copy()
            qd.pop(self.page_kwarg, None)
            return qd.urencode()

    在其他页面的链接中,然后添加 urlencode_filter() 值:

    &lt;li&gt;&lt;a href="?page={{ page_obj.previous_page_number }}<strong>&amp;amp;{{ view.urlencode_filter }}</strong>" style="color: wheat;"&gt;&amp;laquo;&lt;/a&gt;&lt;/li&gt;

    并使用 all 指向上一页、下一页和任意页面的链接来执行此操作。

    【讨论】:

    • 使用您的代码并在浏览器中跳转到第 2 页时,我看到 localhost:8000/sales/list/?page=2%20& 和相同的错误。我将代码复制到 ListView 和模板中的其他内容中。非常感谢您的宝贵时间!
    • & 符号前不应有空格 (&amp;amp;)。
    • @GuillermoZooby:是的,number }}&amp;{{ 之间没有空格。
    • 喜欢这个???
    • »
    【解决方案2】:

    您还可以创建一个自定义的param_replace 模板标签来只更新一个查询参数并保留所有其他参数:

    <a href="?{% param_replace page=page_obj.previous_page_number %}">&laquo;</a>
    

    详情见:https://www.caktusgroup.com/blog/2018/10/18/filtering-and-pagination-django/https://stackoverflow.com/a/22735278/10987661

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签