Джанго: по-разному нумерация страниц на первой странице - PullRequest
3 голосов
/ 28 июня 2009

В настоящее время я использую object_list Джанго для обработки нумерации страниц. Я рад перейти на соответствующий класс Paginator (), если вы считаете, что он мне нужен после того, как вы услышите мою проблему:

На главной странице я хочу разбить на страницы 7 , но на все остальные страницы Я хочу разбить на страницы 10 .

Как бы я поступил так? Я действительно не могу разобраться с этим. Самое близкое к тому, чтобы я заработал, привело к тому, что была исключена целая страница результатов, поэтому, очевидно, я этого не хочу.

Буду очень признателен за любые ответы. Дайте мне знать, если вам нужна дополнительная информация. Большое спасибо.

Джо

Ответы [ 4 ]

6 голосов
/ 28 июня 2009

Просто from django.core.paginator import Paginator и создайте объект paginator как p = Paginator(thestuff, 7) в представлении для домашней страницы, p = Paginator(thestuff, 10) везде. Затем в любом случае свяжите p в контексте, который вы используете для рендеринга шаблона. p.object_list будет установлен соответствующим образом в любом случае (и вы, похоже, говорите, что вы используете именно такой подход, верно?

Django документы имеют отличные детали и примеры (при условии, что вы на 1.0 или лучше). Если вы не можете заставить его работать, можете ли вы показать нам (упрощенную версию, которая все еще не работает) вашего шаблона и просмотреть код?

Редактировать: проблема теперь четко показана, и я думаю, что она должна быть решена путем создания подкласса основного пагинатора Django следующим образом:

from django.core.paginator import Paginator, Page

class MyPaginator(Paginator):

  def __init__(self, **kw):
    self.deltafirst = kw.pop('deltafirst', 0)
    Paginator.__init__(self, **kw)

  def page(self, number):
    "Returns a Page object for the given 1-based page number."
    number = self.validate_number(number)
    if number == 1:
      bottom = 0
      top = self.per_page - self.deltafirst
    else:
      bottom = (number - 1) * self.per_page - self.deltafirst
      top = bottom + self.per_page
    if top + self.orphans >= self.count:
      top = self.count
    return Page(self.object_list[bottom:top], number, self)

Теперь используйте MyPaginator точно так же, как приведенный выше текст и примеры показывают использование Django, за исключением того, что при его создании используйте дополнительный именованный аргумент deltafirst=3, чтобы сделать первую страницу на 3 короче, чем обычная длина на страницу (из 10). Таким образом, вы будете использовать одиночный paginator с номинальной длиной 10, но по меньшей мере с 3, чтобы сделать первую страницу 3 короче, чем все остальные.

(Могут быть проблемы в validate_number, но я не уверен, что они появятся - если они появятся, MyPaginator также потребуется переопределить этот метод).

1 голос
/ 28 июня 2009

Функция object_list () использует Paginator для разбиения списка. Итак, если вы измените «размер» кусков (7 против 8) ... тогда он сделает то, что вы видите.

Выбор: Этот последний выбор шаткий. Не делайте этого :-) Либо «взломайте», либо перейдите на Paginator.

Взломай это ... по запросам> стр. 1, добавь что-то еще в row_list. Я предполагаю, что вы могли бы принудительно ввести его в список с помощью list (row_list) и добавить None или что-то еще через row_list.insert (0, None)

Paginate ... используйте Paginator

Представление + шаблон ... ваше представление просто передает список строк набора запросов в шаблон. Попросите шаблон проверить страницу 1. Есть ли у вас петля / отображение подмножества row_list там? Глупо иметь такую ​​логику в своем шаблоне. Это делает для сложного шаблона.

0 голосов
/ 06 июня 2013

Для моего конкретного сценария я искал разбиение на объекты внутри одного визуализированного шаблона (создание многостраничного документа). В моем случае, я думаю, что самый простой подход - забыть о paginator и использовать вместо него генератор.

    def pages_iter():
        page_num = 1
        num_records = lambda x: 30 if x > 1 else 10
        end_idx = 0

        while True:
            start_idx = end_idx
            end_idx += num_records(page_num)
            yield {
                'number': page_num,
                'object_list': donors[start_idx:end_idx]
            }

            if end_idx > donors.count() - 2:
                break
            page_num += 1

Добавьте { pages: page_iter } в контекст вашей страницы, и тогда у вас есть переменная paginator. Обратите внимание, что num_records - это функция, которая принимает номер_страницы, поэтому вы действительно обладаете максимальной гибкостью.

В вашем шаблоне вы можете обращаться с этим так же, как со страницей:

{% for page in pages %}
  {% if page.number == 1 %}
    {{ header }}
  {% endif %}

  {% for obj in page.object_list %}
    {{ obj }}
  {% endfor %}
{% endfor %}
0 голосов
/ 07 декабря 2012

Я понимаю, что это старый вопрос, но если кто-то, как я, придет сюда и обнаружит, что мой юнит-тест обнаружил проблему.

Алекс, по сути, прав, но не забудьте также реализовать _get_num_pages с self.orphans + self.deltafirst, иначе последняя страница не будет правильной.

def _get_num_pages(self):
    """Returns the total number of pages."""
    if self._num_pages is None:
        if self.count == 0 and not self.allow_empty_first_page:
            self._num_pages = 0
        else:
            hits = max(1, self.count - self.orphans + self.deltafirst)
            self._num_pages = int(ceil(hits / float(self.per_page)))
    return self._num_pages
num_pages = property(_get_num_pages)

И unittest:

def test_ads_paginator(self):
    per_page = 10
    num_items = 100
    num_firstpage = 5
    expected_num_pages = 11

    items = range(num_items)
    paginator = AdsPaginator(items, per_page, deltafirst=per_page-num_firstpage)
    last_item = paginator.page(paginator.num_pages).object_list[-1]

    self.assertEqual(len(paginator.page(1)), num_firstpage)
    self.assertEqual(paginator.num_pages, expected_num_pages)
    self.assertEqual(last_item, items[-1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...