代码之家  ›  专栏  ›  技术社区  ›  Diogo Silva

如何使用django_过滤器分页

  •  0
  • Diogo Silva  · 技术社区  · 6 年前

    在templateview中使用了django_过滤器后,我遇到了分页问题。 在使用django_过滤器之前,我的分页工作正常,但现在它显示了每个页面中的所有项目,我一直在网上寻找,但我没有找到一个很好的解决方案。 我怎样才能修好它? 谢谢

    我的过滤器.py

    class SnippetFilter(django_filters.FilterSet):
        area = []
        tecnology = Technology.objects.values('parent_area').distinct().order_by('parent_area_id')
        for a in tecnology:                                                                         
            area.append(a['parent_area']) 
    
        parent_area = django_filters.ModelMultipleChoiceFilter(queryset=ApplicationArea.objects.filter(id__in=area), widget=forms.CheckboxSelectMultiple)
    
        class Meta:
            model = Technology
            fields = ['title', 'category', 'kind', 'patent', 'patent_type', 'parent_area']
    

    我的视图.py

    class TechnologyListView(LoginRequiredMixin, ListView):
        model = Technology
        template_name = "technology/technology.html"
        paginate_by = 9
    
        def get_queryset(self, *args, **kwargs):
            queryset = super(TechnologyListView, self).get_queryset()
            if self.request.user.is_authenticated and self.request.user.is_superuser or self.request.user.is_authenticated and self.request.user.is_staff:
                queryset = Technology.objects.all()
            elif self.request.user.is_authenticated and self.request.user.is_technology:
                queryset = Technology.objects.filter(user=self.request.user).order_by('-id')
            return queryset
    
        def get_context_data(self, **kwargs):
            selected_elements = []
            data = super(TechnologyListView, self).get_context_data(**kwargs)
            if self.request.user.is_authenticated and self.request.user.is_technology:
                data['finished'] = Technology.objects.filter(user=self.request.user, category=0).count()
                data['developed'] = Technology.objects.filter(user=self.request.user, category=1).count()
                data['product'] = Technology.objects.filter(user=self.request.user, kind=0).count()
                data['process'] = Technology.objects.filter(user=self.request.user, kind=1).count()
                data['software'] = Technology.objects.filter(user=self.request.user, kind=2).count()
                data['deposited'] = Technology.objects.filter(user=self.request.user, patent=0).count()
                data['licensed'] = Technology.objects.filter(user=self.request.user, patent=1).count()
                data['donthave'] = Technology.objects.filter(user=self.request.user, patent=2).count()
            elif self.request.user.is_authenticated and self.request.user.is_superuser or self.request.user.is_authenticated and self.request.user.is_staff :          
                data['finished'] = Technology.objects.filter(category=0).count()
                data['developed'] = Technology.objects.filter(category=1).count()
                data['product'] = Technology.objects.filter(kind=0).count()
                data['process'] = Technology.objects.filter(kind=1).count()
                data['software'] = Technology.objects.filter(kind=2).count()
                data['deposited'] = Technology.objects.filter(patent=0).count()
                data['licensed'] = Technology.objects.filter(patent=1).count()
                data['dontthave'] = Technology.objects.filter(patent=2).count()
    
            data['filter'] = SnippetFilter(self.request.GET, queryset=self.get_queryset())
    
            return data
    

    模板.html

         <div class="container-fluid" >
            <div class="row">        
                <div class="col-sm-2">
                    <div style="margin-top:20%; margin-bottom:25% ">
                        <h1 class="title text-center">Filtro:</h1>
                        <form method="GET" action="{% url 'technology:tech_index' %}" novalidate>
                            {{filter.form|bootstrap}}
    
                            <a class="btn btn-rw btn-danger" href="{% url 'technology:tech_index' %}">Limpar Filtro</a>
                            <input type='submit' value='Procurar' class='btn btn-rw btn-primary'>                    
                        </form>
                    </div>
                </div>
    
                <div class="col-sm-8 col-sm-offset-1">
                    <br>                  
                    <a class="btn btn-rw btn-primary" href="{% url 'technology:create_tech' %}"><i class="fa fa-bolt">
                    </i>Adicionar Tecnologia</a>                            
    
    
                    <h1 class="title text-center">Minhas Tecnologias</h1>
    
    
                    {% if filter.qs.count > 0 %}
    
    
                    <div class="tab-content tab-shop mt15" style="align-items: center !important;">
                        <div class="row" >
                            <div class="col-sm-4 col-md-4 col-lg-4">
                                <canvas id="category"></canvas>
                            </div>  
                            <div class="col-sm-4 col-md-4 col-lg-4">
                                <canvas id="type" ></canvas>
                            </div>    
                            <div class="col-sm-4 col-md-4 col-lg-4">
                                <canvas id="patent"></canvas>
                            </div> 
                            <!-- <div class="col-lg-3 col-md-3 col-sm-3">
                                <canvas id="area_ap" width="80" height="80"></canvas>
                            </div>   -->
                        </div>
                        <br>
                    </div>
                    <br>
                    <div class="tab-content tab-shop mt15">
    
    
                        <div id="home" class="tab-pane row fade in active">
    
                            {% for item in filter.qs %}        
                            <div class="col-lg-4 col-md-4 col-sm-6 mb30">
                                <div class="view  no-margin" style="background-color: #cfcfcf">
                                    <!-- Blog Thumb -->
                                    <div class="product-container">
    
                                        {% if item.area_img %}                                                      
                                        <img class="img-responsive full-width" style="width:100%; height:200px" src="{{item.area_img.image.url}}" alt="..."> 
                                        {% else %}
                                        <img class="img-responsive full-width" style="width:100%; height:200px" src="{% static 'images/notavailable.png' %}" alt="...">                                                
                                        {% endif %}                                                                                          
    
                                    </div>
                                    <div class="mask">
                                        <div class="image-hover-content">
                                                <!-- Zoom + Blog Link -->
                                                <a href="{% url 'technology:detail_tech' item.pk %}"  >
                                                    <div class="image-icon-holder"><span data-toggle="tooltip" data-placement="top" title="Visualizar" class="ion-eye image-icons"style="color:#fff"></span></div>
                                                </a>
                                                {% if request.user.is_authenticated and request.user.is_technology %}                                                                                                      
                                                    <a href="{% url 'technology:update_tech' item.pk %}">
                                                        <div class="image-icon-holder"><span  data-toggle="tooltip" data-placement="top" title="Editar" class="ion-edit image-icons" style="color:#fff"></span></div>
                                                    </a>
                                                    <a data-toggle="modal" data-target="#delete-{{item.pk}}">
                                                        <div class="image-icon-holder"><span data-toggle="tooltip" data-placement="top" title="Deletar" class="ion-ios7-trash image-icons" style="color:red"></span></div>
                                                    </a>
                                                    {% endif %}
    
                                                    <div class="modal fade" id="delete-{{item.pk}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                                                        <div class="modal-dialog" role="document">
                                                            <div class="modal-content text-center">
                                                                <form action="{% url 'technology:delete_tech' pk=item.pk %}" method="post">
                                                                    {% csrf_token %}
                                                                    <div class="modal-header">
                                                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                                                                        <h2>Deletar</h2>
                                                                    </div>
                                                                    <div class="modal-body">
                                                                        <p>Você deseja realmente deletar "{{ item }}"?</p>
                                                            </div>
                                                            <div class="modal-footer">
                                                                <button type="button" class="btn btn-success" data-dismiss="modal">Voltar</button>
                                                                <input class="btn btn-danger" type="submit" value="Confirmar" />
                                                            </div>
                                                        </form>
                                                        </div>
                                                    </div>
                                                </div>
    
                                            </div><!-- /image hover content -->
                                        </div><!-- /mask-->
                                    </div>
                                    <div class="shop-product content-box-shadow">
                                        <a href="{% url 'technology:update_tech' item.pk %}"><h2>{{item.title}}</h2></a>
                                        {% if item.description %}                                          
                                            <p>{{item.description|truncatechars:40}}</p>
                                        {% else %}
                                            <p class="text-danger">Não há descrição</p>
                                        {% endif %}
                                    </div>
                                </div>
                                {% if forloop.counter|divisibleby:4 %}
                            </li>
                                <li>
                                    {% endif %}
                        {% endfor %}
                    </div>
                </div>
                {% include "includes/paginator.html" %}
                {% else %}
                <div class="tab-content tab-shop mt15 text-center " style="padding-top: 25%; padding-bottom: 25%">
                    <div class="row">
                        <h1 class="text-info">Nenhuma tecnologia cadastrada</h1>
                    </div>
                </div>
                {% endif %}
            </div>
        </div>
    

    paginator.html

    {% if is_paginated %}
        <ul class="pagination">
            {% if page_obj.has_previous %}
                <li class="page-item">
                    <a href="?page={{ page_obj.previous_page_number }}">&laquo;</a>
                </li>
            {% else %}
                <li class="disabled"><span class="page-link">&laquo; 
                </span></li>
            {% endif %}
    
             {% for page_num in paginator.page_range %}
                 {% if page_obj.number == page_num %}
                     <li class="page-item active">
                        <span class="page-link">
                           {{ page_num }}
                           <span class="sr-only">(current)</span>
                        </span>
                     </li>
                 {% elif page_num > page_obj.number|add:'-2' and page_num < page_obj.number|add:4 %}
                     <li class="page-item">
                         <a class="page-link" href="?page={{ page_num }}">{{page_num}}</a>
                     </li>
                 {% endif %}
              {% endfor %}
    
    
              {% if page_obj.has_next %}
                 <li class="page-item">
                    <a class="page-link" href="?page={{ page_obj.next_page_number }}">&raquo;</a></li>
              {% else %}
                  <li class="page-item disabled">
                      <span class="page-link">
                &raquo;
                      </span>
                  </li>
              {% endif %}
    
    
        </ul>
     {% endif %}
    
    2 回复  |  直到 6 年前
        1
  •  4
  •   D. Starr    6 年前

    我遇到这个问题有一段时间了,我发现这个解决方案是我最喜欢的。

    django过滤器的filterview已经支持与listview相同的分页,只是如何使其工作并不十分明显。您可以在应用筛选器时更改浏览器地址栏中的“page=2”来尝试此操作,并确保它将转到下一个正确的页面。

    所以让它工作只是几个步骤…

    创建一个视图MIXIN,它分离出“页面”关键字(默认为Django的分页),并将剩余的查询字符串返回为一个新的模板上下文变量。

    class PaginatedFilterViews(View):
        def get_context_data(self, **kwargs):
            context = super(PaginatedFilterViews, self).get_context_data(**kwargs)
            if self.request.GET:
                querystring = self.request.GET.copy()
                if self.request.GET.get('page'):
                    del querystring['page']
                context['querystring'] = querystring.urlencode()
            return context
    

    然后在所有要分页的filterviews中包含此新对象…即:

    class FilteredList(PaginatedFilterViews, FilterView):
        model = Whatever
        paginate_by = 10 # or whatever
        # the rest of your view code
    

    并更新分页模板以插入django筛选器的查询字符串的其余部分…

    {% if page_obj.has_previous %}
        <li>
            <a href="?page=1{% if querystring %}&amp;{{ querystring }}{% endif %}">
                <i class="icon-page-first"></i>
                <span class="btn-text">First</span>
            </a>
        </li>
        <li>
            <a href="?page={{ page_obj.previous_page_number }}{% if querystring %}&amp;{{ querystring }}{% querystring %}">
                <i class="icon-page-back"></i>
                <span class="btn-text">Prev</span>
            </a>
        </li>
    {% else %}
        <li class="disabled">
            <span class="icon-page-first">
                <span class="btn-text">First</span>
            </span>
        </li>
        <li class="disabled">
            <span class="icon-page-back">
                <span class="btn-text">Prev</span>
            </span>
        </li>
        {# etc etc #}
    {% endif %}
    

    在许多视图中对我都很好,不需要其他第三方依赖项。

        2
  •  1
  •   cander    6 年前

    就我个人而言,我使用带有django过滤器的django表,这会帮我处理分页,所以我不是这方面的专家。但是,在视图中显示筛选结果后,似乎需要对其分页。也许是这样的?

    paginator = Paginator(data, 10)
    

    看看这篇文章。 Django Filter with Pagination 而且这个网站也解释了如何做一般。 https://djangopy.org/how-to/pagination-with-django/