【问题标题】:Pagination in Wagtail鹡鸰中的分页
【发布时间】:2017-03-14 21:54:18
【问题描述】:

我对 Wagtail 还很陌生,我正在创建一个包含资源(博客)部分的网站,但我不确定如何实现分页,以便每个页面上只有 5 个帖子用户必须单击一个数字(1、2、3 等)才能转到下一页以查看接下来的 5 个帖子。

我在资源/博客索引页面的分页部分的模板中有这个:

<ul class="pagination">
  <li><a href="#"><i class="fa fa-angle-left"></i></a></li>
  <li class="active"><a href="#">1</a></li>
  <li><a href="#">2</a></li>
  <li><a href="#">3</a></li>
  <li><a href="#"><i class="fa fa-angle-right"></i></a></li>
</ul>

我需要合并哪些代码才能使其正常工作?提前致谢。

【问题讨论】:

    标签: django pagination blogs wagtail


    【解决方案1】:

    Django 为此提供了模块django.core.paginatorhttps://docs.djangoproject.com/en/1.10/topics/pagination/。在 Wagtail 中使用它与 Django 文档中的示例非常相似 - 唯一真正的区别是,当您设置要传递给模板的 Paginator 对象时,您可以使用 get_context 方法在页面模型,而不是视图函数。您的模型定义将如下所示:

    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    class ResourceIndexPage(Page):
        # ...
        def get_context(self, request):
            context = super(ResourceIndexPage, self).get_context(request)
    
            # Get the full unpaginated listing of resource pages as a queryset -
            # replace this with your own query as appropriate
            all_resources = ResourcePage.objects.live()
    
            paginator = Paginator(all_resources, 5) # Show 5 resources per page
    
            page = request.GET.get('page')
            try:
                resources = paginator.page(page)
            except PageNotAnInteger:
                # If page is not an integer, deliver first page.
                resources = paginator.page(1)
            except EmptyPage:
                # If page is out of range (e.g. 9999), deliver last page of results.
                resources = paginator.page(paginator.num_pages)
    
            # make the variable 'resources' available on the template
            context['resources'] = resources
    
            return context
    

    在您的模板中,您现在可以使用{% for resource in resources %} 循环遍历项目,并显示分页链接,如下所示:

    <ul class="pagination">
      {% if resources.has_previous %}
        <li><a href="?page={{ resources.previous_page_number }}"><i class="fa fa-angle-left"></i></a></li>
      {% endif %}
      {% for page_num in resources.paginator.page_range %}
        <li {% if page_num == resources.number %}class="active"{% endif %}><a href="?page={{ page_num }}">{{ page_num }}</a></li>
      {% endfor %}
      {% if resources.has_next %}
        <li><a href="?page={{ resources.next_page_number }}"><i class="fa fa-angle-right"></i></a></li>
      {% endif %}
    </ul>
    

    【讨论】:

    • 只是想补充一点,我在最后一个 &lt;li&gt;&lt;/li&gt; 周围使用了以下内容,仅在有下一页时才显示下一个箭头 - {% if resources.has_next %} {% endif %}
    • 不错。这真的很好用。有什么方法可以更新它,以便我可以使用包含 /page/1/ 的漂亮 url?目前我正在乱搞,但很乱!
    【解决方案2】:

    非常感谢您让我来到这里 - 非常感谢您的帮助。我必须进行一些调整才能使其正常工作。如果有人遇到同样的问题,这里是模型:

    class NewsIndexPage(Page):
    intro = RichTextField(blank=True)
    
    def get_context(self, request):
        context = super(NewsIndexPage, self).get_context(request)
    
        # Get the full unpaginated listing of resource pages as a queryset -
        # replace this with your own query as appropriate
        blogpages = self.get_children().live().order_by('-first_published_at')
    
        paginator = Paginator(blogpages, 3) # Show 3 resources per page
    
        page = request.GET.get('page')
        try:
            blogpages = paginator.page(page)
        except PageNotAnInteger:
            # If page is not an integer, deliver first page.
            blogpages = paginator.page(1)
        except EmptyPage:
            # If page is out of range (e.g. 9999), deliver last page of results.
            blogpages = paginator.page(paginator.num_pages)
    
        # make the variable 'resources' available on the template
        context['blogpages'] = blogpages
    
        return context
    

    ...这是 HTML:

    <ul class="pagination">
        {% if blogpages.has_previous %}
          <li>
            <a href="?page={{ blogpages.previous_page_number }}"><i class="fa fa-angle-left"></i></a>
          </li>
        {% endif %}
        {% for page_num in blogpages.paginator.page_range %}
          <li {% if page_num == blogpages.number %} class="active"{% endif %}>
            <a href="?page={{ page_num }}">{{ page_num }}</a>
          </li>
        {% endfor %}
        {% if resources.has_next %}
          <li>
            <a href="?page={{ blogpages.next_page_number }}"><i class="fa fa-angle-right"></i></a>
          </li>
          {% endif %}
      </ul>
    

    它就像一个魅力 - 并增加了学习曲线!

    【讨论】:

      【解决方案3】:

      如果它对任何人都有用,我希望它与class-based view ListView 尽可能接近,所以我最终得到了这个:

      from django.core.paginator import Paginator, InvalidPage
      from django.http import Http404
      from django.utils.translation import gettext as _
      
      from wagtail.core.models import Page
      
      class ArticleListPage(Page):
      
          # Some Page variables set here. #
      
          # Pagination variables:
          paginator_class = Paginator
          paginate_by = 10
          page_kwarg = 'page'
          paginate_orphans = 0
          allow_empty = False
      
          def get_context(self, request):
              context = super().get_context(request)
      
              queryset = Page.objects.live()
      
              paginator, page, queryset, is_paginated = self.paginate_queryset(
                                              queryset, self.paginate_by, request)
              context.update({
                  'paginator': paginator,
                  'page_obj': page,
                  'is_paginated': is_paginated,
                  'object_list': queryset,
              })
      
              return context
      
          def paginate_queryset(self, queryset, page_size, request):
              """
              Adapted from the ListView class-based view.
              Added the request argument.
              """
              paginator = self.paginator_class(
                                          queryset,
                                          self.paginate_by,
                                          orphans=self.paginate_orphans,
                                          allow_empty_first_page=self.allow_empty)
              page_kwarg = self.page_kwarg
              page = request.GET.get(page_kwarg) or 1
      
              try:
                  page_number = int(page)
              except ValueError:
                  if page == 'last':
                      page_number = paginator.num_pages
                  else:
                      raise Http404(_("Page is not 'last', nor can it be converted to an int."))
              try:
                  page = paginator.page(page_number)
                  return (paginator, page, page.object_list, page.has_other_pages())
              except InvalidPage as e:
                  raise Http404(_('Invalid page (%(page_number)s): %(message)s') % {
                      'page_number': page_number,
                      'message': str(e)
                  })
      

      这将在您的模板中为您提供与普通 Django ListView 相同的 paginatorpage_objis_paginatedobject_list 变量。

      (使用 python 3、Django 2.1 和 Wagtail 2.3。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        相关资源
        最近更新 更多