【问题标题】:How can django-cms plugins be displayed using pagination如何使用分页显示django-cms插件
【发布时间】:2014-06-11 05:04:44
【问题描述】:

我写了两个 django-cms 插件来显示图片库和视频。

这些附件在 /gallery//videos/ 的 CMS 页面上,其中每个模板都有一个占位符,允许包含相应的插件。

在我有gallery.htmlvideo.html 将所有插件实例呈现到页面的基础级别,我希望能够附加endless 进行分页。

这是一项非常简单的任务,可以在图库中对图像进行分页,因为我在 gallery 中有一个 apphook 视图来收集所有图像的列表,然后就像 {% pagingate images %} {% for image in images %} 等一样简单模板。

但是,在 django-cms 控制所有插件实例的收集和渲染的模板中,我失去了控制,如何对插件进行分页?

我已经开始在/gallery/ 索引上使用apphook 的路线,但要完成这一点,我可以想象我需要停止 django-cms 执行它默认执行的操作以及应该执行的操作剩下要做的。所以我需要一些关于工作的最佳方法的指导/建议。不管怎样,这里有一些代码;

# views.py
    def gallery_index(request, *args, **kwargs):

        template = request.current_page.template
        placeholder_id = request.current_page.placeholders.get(slot='gallery').id

        gallery = Placeholder.objects.get(id=placeholder_id)
        galleries = gallery.cmsplugin_set.all()

        return render_to_response(
            template,
            {'galleries': galleries},
            context_instance=RequestContext(request)
        )

# gallery.html
    <h3>GALLERIES</h3>

    <div id="panel-area" class="gallery_grid">
        <ul id="galleries" class="gridview" style="width: 800px;">
    {% paginate galleries %}
        {% for gallery in galleries %}
            <li>{{ gallery }}</li> <!-- testing the pagination -->
        {% endfor %}
    {% placeholder "gallery" %}
        </ul>
    {% show_pages %}

# cms_plugins.py
    class ImageGalleryPlugin(CMSPluginBase):

        name = _('Image Gallery')
        model = ImageGalleryPlugin
        form = ImageGalleryAdminForm
        render_template = 'single_gallery.html'

        def render(self, context, instance, placeholder):

            context.update({'gallery': instance,})        
            return context

# single_gallery.html
    <li class="gallery_top">
    <span class="title">
        <a href="{% url 'image_gallery_page' page_id=request.current_page.id gallery_id=gallery.id %}">{{ gallery.event_date|date:"d/m/Y" }}<br/>
             <p class="sub-text">View more of {{ gallery.event_name }}</p></a>
    </span>
        <img src="{{ gallery.display_random.gallery_display }}" alt="" border="0" />
    </li>

我当前的解决方案是 jQuery 解决方案,但我希望这一切都由 django 无休止的分页控制,以保持行为和设计的一致性。

【问题讨论】:

  • django.contrib.pagination 需要访问 GET 变量,例如 URL 上的“page”。因此,不建议在 djangoCMS 插件的上下文中进行分页:如果您的用户在同一页面上安装了两个分页插件怎么办?如果页面上的主要内容(非插件)是分页的怎么办?会出现混乱!我想,您可以在每个插件的基础上覆盖 GET var 名称,但是如果您的用户在页面上多次安装同一个插件,这仍然无济于事。
  • 如果您希望使用 CMS 应用程序来执行此操作,那就太好了!一定要在这里阅读这个主题:docs.djangoproject.com/en/dev/topics/pagination 另外,你应该知道 Django 中的基于类的视图系统内置了对分页的支持。在这里查看:ccbv.co.uk/projects/Django/1.6/django.views.generic.list/…
  • 谢谢@mkoistinen。我很高兴采用“它违背插件的理想”的思维方式,但我认为如果用户想要在一个页面中有很多实例,那么将它作为管理员中的一个选项会很好(这对于图片画廊的页面当然是可能的)。

标签: django plugins pagination django-cms


【解决方案1】:

去过那里。 Django CMS 插件中的分页确实有问题。

解决问题的一种可能方法

  1. 实现分页 API 端点以获取对象。例如,使用django.views.generic.list.ListView。它有很好的内置分页功能。
  2. 在 CMS 插件中,使用 AJAX 从 API 端点获取对象。 CMS 插件不需要知道要渲染哪些对象,它只需要知道它可以从哪里获取对象(API 端点)。

这种方法需要前端代码来获取正确的对象、更新 UI、跟踪当前页面等等,但可以(并且已经)成功地用于实现分页的 Django CMS 插件。

【讨论】:

    【解决方案2】:

    这是我在 django cms 插件中添加分页的快速解决方案

    from cms.models.pagemodel import Page
    from cms.plugin_base import CMSPluginBase
    from django.http import Http404
    from django.core.paginator import InvalidPage, Paginator
    
    
    class MyPlugin(CMSPluginBase):
    
        def render(self, context, instance, placeholder):
            query_set = Page.objects.filter(is_page_type=False)
            page = context['request'].GET.get('page') or 1
            paginator, page, queryset, is_paginated = self.paginate_queryset(page, query_set, 6)
            context.update({'paginator': paginator,
                            'page_obj': page,
                            'is_paginated': is_paginated,
                            'object_list': queryset
                            })
            return context
    
        def paginate_queryset(self, page, queryset, page_size):
            paginator = Paginator(queryset, page_size)
            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)
                })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      • 2014-07-18
      • 2014-09-21
      • 1970-01-01
      • 2017-03-20
      • 2011-04-06
      • 1970-01-01
      相关资源
      最近更新 更多