【问题标题】:Django pagination return all elements but still paginateDjango分页返回所有元素但仍然分页
【发布时间】:2016-02-20 04:10:19
【问题描述】:

我正在尝试用 django 做一些应该简单易行的事情:

对项目列表进行分页。

所以,我有一个文章页面,我想每页最多显示 10 篇文章,下一页 = 10 篇下一篇文章等等。

您可以按某些类别作为来源或日期对它们进行排序。

所以,当我到达 mydomaine.com/articles/ 时,我的所有元素都显示出来了。

如果我按来源排序,如这个 views.py 所示:

class SourceEntriesView(ContextSourcesMixin, BaseArticleView, BaseArticleListView):
model = Article
context_object_name = 'article_list'
template_name = 'base_templates/template_press.html'
_source = None
paginate_by = get_setting('PAGINATION')
view_url_name = 'djangocms_press:articles-source'

@property
def source(self):
    if not self._source:
        try:
            source_qs = ArticleSource.objects.active_translations(
                get_language(),
                slug=self.kwargs['source']
            )

            #source_qs = source_qs.filter(site=Site.objects.get_current().pk)
            self._source = source_qs.latest('pk')
        except ArticleSource.DoesNotExist:
            raise Http404("ArticleSource does not exist for this site")
    return self._source

def get_queryset(self):
    qs = super(SourceEntriesView, self).get_queryset()
    if 'source' in self.kwargs:
        qs = qs.filter(sources__pk=self.source.pk)
    return qs

def get_context_data(self, **kwargs):
    kwargs['source'] = self.source
    return super(SourceEntriesView, self).get_context_data(**kwargs)

一旦调用 ajax 来加载此视图并显示按来源排序的文章,我就有了 10 个项目! (好吧,我在测试时尝试使用 4)。

那么为什么它不能在主页上运行。

下面是我的代码的更多解释:

''' Main article display view '''
class ArticleListView(FormMixin, BaseArticleListView, ContextSourcesMixin):
  model = Article
  context_object_name = 'article_list'
  template_name = 'base_templates/template_press.html'
  view_url_name = 'djangocms_press:articles-list'
  form_class = SourcesRegionsFilterForm
  paginate_by = get_setting('PAGINATION')


def get_form_kwargs(self):
    return {
        'initial': self.get_initial(),
        'prefix': self.get_prefix(),
        'data': self.request.GET or None,
        'request': self.request,
    }

def get(self, request, *args, **kwargs):
    """
    Handle the form submissions to filter by Sources and regions
    First_object is use for pagination
    """
    context = {}

    self.object_list = self.get_queryset().order_by("-date_realization")

    first_object = 0

    if 'article' in self.request.GET:
        try:
            project_id = int(request.GET['article'])
            context['article_render'] = self.object_list.get(pk=project_id)
        except (Article.DoesNotExist, ValueError):
            pass

    form = self.get_form(self.form_class)

    if form.is_valid():
        if form.cleaned_data['regions']:
            self.object_list = self.object_list.filter(
                Q(regions__continent=form.cleaned_data['regions']) | Q(global_regions=True)).distinct()

    context.update(self.get_context_data(form=form))

    context['load_more_url'] = self.get_load_more_url(request, context)

    context[self.context_object_name] = self.object_list
    context['object_list'] = self.object_list
    source_qs = ArticleSource.objects.active_translations(get_language())
    context['sources_list'] = source_qs
    date_realization_for_articles = Article.objects.values_list('date_realization',
                                                        flat=True).distinct()
    context['dates_realization'] = date_realization_for_articles.dates('date_realization', 'month', order="DESC")

    return self.render_to_response(context)

def get_load_more_url(self, request, context):
    args = request.GET.copy()
    return '?{}'.format(args.urlencode())

def render_to_json_response(self, context, **response_kwargs):
    if 'current_app' not in context:
        context['current_app'] = resolve(self.request.path).namespace

    c = RequestContext(self.request, context)

    html_items_list = render_to_string(
        'base_templates/template_press.html',
        context,
        context_instance=c)

    html_items_list = html_items_list.strip()

    json_response = {
        'html_items_list': html_items_list,
        'load_more_url': self.get_load_more_url(self.request, context),
    }

    return JsonResponse(json_response)

def render_to_response(self, context):
    if self.request.is_ajax():
        response = self.render_to_json_response(context)
    else:
        response = super(ArticleListView, self).render_to_response(context)
    return response

这是显示文章的主视图。

我的设置,很简单但更容易使用:

def get_setting(name):
  from django.conf import settings
  from meta_mixin import settings as meta_settings

  default = {
    'PRESS_PAGINATION': getattr(settings, 'PRESS_PAGINATION', 4),
  }
  return default['PRESS_%s' % name]

我也尝试在文章列表 url 中传递 paginated_by,但结果是一样的。

这是我的模板部分,假设是分页的:

    {% if article_list %}
    <div id="articles-list" class="col-md-12">
        {% for article in article_list %}
        <div class="row article">
            <div class="col-md-2">
                {{ article.date_realization|date:"F d, Y" }}
            </div>
            <div class="col-md-2">
                {{ article.source }}
            </div>
            <div class="col-md-2">
            {% for region in article.regions.all %}
                {{ region.name }}
            {% endfor %}
            </div>
            <div class="col-md-6">
                {{ article.title }}
            </div>
        </div>
        {% endfor %}
    </div>
    {% if is_paginated %}
    <section id="content-btn">
        <div id="load-more-btn blippar-white-btn" class="col-md-2 col-md-offset-5 col-xs-8 col-xs-offset-2" align="center">
                <a id="loadmore" role="button" class="button btn load-more-btn blippar-white-btn" href="{{ load_more_url }}">{% trans 'VIEW MORE' %}</a>
        </div>
    </section>

    <div class="col-lg-12">

        <span class="current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
        {% endif %}

    </div>

    {% endif %}
{% endif %}

所以,我有两个问题:

  1. 为什么它没有显示在主文章列表中?
  2. 为什么在选择一个来源后,如果我点击“下一步”,我的所有项目都会显示出来?

如果您有想法或反思方向,我会喜欢的 :)

【问题讨论】:

  • 问题描述不清晰:当你进入错误视图(ArticleListView)时你没有任何结果?然后,当您选择一个来源时,您会突然获得所有结果而无需分页?
  • 在错误的视图中,我的所有文章都显示,没有分页,当我选择一个来源时,它会被分页。
  • 好的,我现在明白了,我想我找到了问题,所以我提出了一个解决方案。

标签: python django pagination


【解决方案1】:

我假设您正在使用 MultipleObjectMixin。

在这种情况下,当您调用 context.update(self.get_context_data(form=form)) 时会发生分页。查看源代码:https://github.com/django/django/blob/master/django/views/generic/list.py

所以当你调用这个函数时,它会将 context['object_list'] 设置为分页内容。不幸的是,当您调用context['object_list'] = self.object_list 时,您会在几行之后覆盖它,因为 self.object_list 不受分页的影响。如果你删除这一行应该没问题。

编辑:您似乎使用的是“article_list”而不是“object_list”,这里有额外的评论:

  • 在您的原始函数中,最后有 'page' 指的是右分页函数,以及 'article_list' 和 'object_list' 指的是我解释的完整文章列表。
  • 在我的解决方案中,'page' 和 'article_list' 仍然没有改变,但 'object_list' 指的是正确的分页列表。不幸的是,我没有注意到它不是您在模板中使用的那个。
  • 所以现在您只需将context[self.context_object_name] = self.object_list 替换为context[self.context_object_name] = context['object_list'],它就会起作用:)

【讨论】:

  • 是的,我试过这个,我知道为什么,但它也不起作用。目前,我唯一的解决方案就是这个答案下的那个:(
  • 我编辑解释了为什么会这样以及如何纠正它,只是上下文键和值的问题:)
【解决方案2】:

所以,目前我有一个临时解决方案:

{% for article in page_obj.object_list %}
        <div class="row article">
            <div class="col-md-2">
                {{ article.date_realization|date:"F d, Y" }}
            </div>
            <div class="col-md-2">
                {{ article.source }}
            </div>
            <div class="col-md-2">
            {% for region in article.regions.all %}
                {{ region.name }}
            {% endfor %}
            </div>
            <div class="col-md-6">
                {{ article.title }}
            </div>
        </div>
        {% endfor %}

而不是这样做:

{% for article in article_list %}
    <div class="row article">
        <div class="col-md-2">
            {{ article.date_realization|date:"F d, Y" }}
        </div>
        <div class="col-md-2">
            {{ article.source }}
        </div>
        <div class="col-md-2">
        {% for region in article.regions.all %}
            {{ region.name }}
        {% endfor %}
        </div>
        <div class="col-md-6">
            {{ article.title }}
        </div>
    </div>
    {% endfor %}

article_list 变成了 object_list。我对此不太满意,因为当我阅读文档时,这应该是不必要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2016-09-16
    相关资源
    最近更新 更多