【问题标题】:Pagination after filtering in django在 django 中过滤后的分页
【发布时间】:2021-03-29 23:04:13
【问题描述】:

我在过滤后尝试使用分页时遇到问题。 我在表格中制作了一个搜索表格。在第一页中,搜索应用程序后显示所有带有条件的合同,但是当我单击第 2 页时,它会刷新并显示其他结果。如果我在搜索表单中重写,它将在第 2 页显示其他结果 在我的 form.py 中

class ContractSearchForm(forms.ModelForm):
    use_required_attribute = False
    export_to_CSV = forms.BooleanField(required=False)
    class Meta:
        model = Contracts
        fields = ["contract","name"]

在我看来.py

def list_contract(request):
    header= "LIST OF CONTRACT"
    form = ContractSearchForm(request.POST or None)

    queryset =Contracts.objects.all()
    
    #pagination
    paginate_by = 10
    paginate_by = request.GET.get('paginate_by', paginate_by) or 10
    user_list = queryset
    
    paginator = Paginator(user_list, paginate_by)
    page = request.GET.get('page',1)
    
    try:
        queryset = paginator.page(page)
    except PageNotAnInteger:
        users = paginator.page(1)
    except EmptyPage:
        users = paginator.page(paginator.num_pages)
    context = {
        "form":form,
        "header": header,
        "queryset": queryset1,
        'paginate_by':paginate_by,
    }
    if request.method == 'POST':
        #Tạo queryset sang filter
        queryset2 = Contracts.objects.filter(contract__icontains=form['contract'].value(),
                                    name__icontains=form['name'].value().upper()
                                    )
        #pagination when search
        paginate_by = 10
        paginate_by = request.GET.get('paginate_by', paginate_by) or 10
        user_list = queryset
        
        paginator = Paginator(user_list, paginate_by)
        page = request.GET.get('page',1)
        
        try:
            queryset = paginator.page(page)
        except PageNotAnInteger:
            users = paginator.page(1)
        except EmptyPage:
            users = paginator.page(paginator.num_pages)
        context = {
            "form":form,
            "header": header,
            "queryset": queryset,
            'paginate_by':paginate_by,
        }

    return render (request, "customer1.html",context)

在 customer1.html 中

{% if queryset.has_previous %}
                      <a href="?{% param_replace page=1 %}">First</a>
                      {% if queryset.previous_page_number != 1 %}
                        <a href="?{% param_replace page=queryset.previous_page_number %}">Previous</a>
                      {% endif %}
                    {% endif %}

                    Page {{ queryset.number }} of {{ queryset.paginator.num_pages }}

                    {% if queryset.has_next %}
                      {% if queryset.next_page_number != queryset.paginator.num_pages %}
                        <a href="?{% param_replace page=queryset.next_page_number %}">Next</a>
                      {% endif %}
                      <a href="?{% param_replace page=paginator.num_pages %}">Last</a>
                    {% endif %}

我的 ulr.py

 urlpatterns = [
        path('admin/', admin.site.urls),
        path('demo',views.showDemoPage),
        path('', include('test_upload_filter.urls')),
        path('add_items/', views.add_items, name='add_items'),
        path('contract_detail/<str:contract_id>/', views.contract_detail, name="contract_detail"),

在我的应用 url.py 中

app_name='example_app'
urlpatterns = [
    path("customer1/",page,name="list_contract")
]

我更新了我的代码,我使用了模板标签 my_tags.py

@register.simple_tag(takes_context=True)
def param_replace(context, **kwargs):

    d = context['request'].GET.copy()
    for k, v in kwargs.items():
        d[k] = v
    for k in [k for k, v in d.items() if not v]:
        del d[k]
    return d.urlencode()

我尝试将 django-filter 与分页一起使用,但 django-filter 无法区分大小写。 我的 url 浏览器在搜索 127.0.0.1:8000/customer1 之后和之前仍然相同,在第 2 页 http://127.0.0.1:8000/customer1/?page=2 感谢您的阅读。抱歉,我的代码太长了,因为我必须重写两次分页功能。

【问题讨论】:

    标签: django search filter pagination


    【解决方案1】:

    我不知道这是否有帮助。我有一个类似的问题,只是调整了分页网址:

    <div id="pagelinks">
        {% if ideas.has_previous %}
        <a class="infinite-more-link" href="{{ request.get_full_path }}&page={{ ideas.previous_page_number }}" style="float:left;">&lt;- Previous ideas<a>
        {% endif %}
        {% if ideas.has_next %}
            <a class="infinite-more-link" href="{{ request.get_full_path }}&page={{ ideas.next_page_number }}" style="float:right;">More ideas -&gt;</a>
        {% endif %}    
    </div>
    

    JavaScript: &lt;script&gt; function Waypoint(){ var infinite = new Waypoint.Infinite({ element: $('.infinite-container')[0] }); } &lt;/script&gt;

    【讨论】:

      【解决方案2】:

      使用你自己的views.py

      那么你需要在 'your_app_name/templatetags/my_tags.py' 根目录中构建一个模板标签,如下代码所示

      my_tags.py

      from django import template
      
      register = template.Library()
      
      
      @register.simple_tag(takes_context=True)
      def param_replace(context, **kwargs):
          d = context['request'].GET.copy()
          for k, v in kwargs.items():
              d[k] = v
          for k in [k for k, v in d.items() if not v]:
              del d[k]
          return d.urlencode()
      

      最终在模板分页中使用该模板标签:

      html 文件

      (别忘了先加载你的标签)

      注意我在哪里使用 param_replace

      {% load my_tags %}
      
      .
      .
      .
      .
      
      <!-- Pagination -->
      <nav aria-label="Page navigation">
          {% if queryset.has_other_pages %}
          <ul class="pagination justify-content-center">
      
              {% if queryset.has_previous %}
              <li class="page-item disabled">
                  <a class="page-link page-link-prev" href="{% url 'url_app_name:current_path_url_name' %}?{% param_replace page=queryset.previous_page_number  %}" aria-label="Previous" tabindex="-1" aria-disabled="true">
                      <span aria-hidden="true"><i class="icon-long-arrow-left"></i></span>Previous
                  </a>
              </li>
              {% endif %}
      
              {% for i in queryset.paginator.page_range %}                    
                  {% if queryset.number == i %}
                  <li class="page-item active" aria-current="page"><a class="page-link" href="#">{{ i }}</a></li>
                  {% else %}
                  <li class="page-item"><a class="page-link" href="?{% param_replace page=i  %}">{{ i }}</a></li>
                  {% endif %}
              {% endfor %}
      
              {% if queryset.has_next %}
              <li class="page-item">
                  <a class="page-link page-link-next" href="{% url 'url_app_name:current_path_url_name' %}?{% param_replace page=queryset.next_page_number  %}" aria-label="Next">
                      Next<span aria-hidden="true"><i class="icon-long-arrow-right"></i></span>
                  </a>
              </li>
              {% endif %} 
      
          </ul>
          {% endif %}
      </nav>
      <!-- Pagination -->
      
      .
      .
      .
      

      让我知道这是否适合你

      我可以给你完整的工作代码,我自己用它来进行多重过滤,你想要的分页

      抱歉,EN 不好(:

      【讨论】:

      • 感谢您的回复。我尝试了您的代码,但是在替换 {% url 'url_app_name:current_path_url_name' %} 时出现问题。如果还保留这条线,就会出现错误。抱歉,我之前没有使用过模板标签,所以我不知道如何正确使用它。如果我删除此代码,它仍然无法显示 2 页。如果你能分享你的工作代码,我可以从你的代码中学到很多有用的东西
      • 什么问题?
      • 'url_app_name' 不是注册的命名空间它显示这个错误
      • 你不应该这样使用这些。我的意思是它的路径名。参考这里:docs.djangoproject.com/en/3.1/ref/urls
      • 第一个参数是你在 urls.py 中指定的 app_name,第二个参数是你的路径名 {% url 'url_app_name:current_path_url_name' %}
      猜你喜欢
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 2018-04-04
      • 2018-07-10
      • 2019-08-17
      • 1970-01-01
      • 2017-06-01
      • 1970-01-01
      相关资源
      最近更新 更多