3

現時点では、ページ付けを処理するためにDjangoのobject_listを使用しています。問題を聞いた後で必要だと思われる場合は、適切なPaginator()クラスに移動できます。

ホームページでは7でページ付けしたいのですが、他のすべてのページでは10でページ付けしたいと思います。

どうすればこれを行うことができますか?私は本当に頭を悩ませることができません。私がそれを機能させるために最も近づいたのは、結果のページ全体が省略された結果だったので、明らかに私はそれを望んでいません。

私はどんな答えにも非常に感謝します。さらに情報が必要な場合はお知らせください。どうもありがとう。

ジョー

4

4 に答える 4

7

ホームページのビューのように、他のすべての場所でページfrom django.core.paginator import Paginator付けオブジェクトを作成します。次に、どちらの場合も、テンプレートのレンダリングに使用するコンテキストでバインドします。どちらの場合も適切に設定されます(そして、それがあなたが使用しているアプローチだと言っているようですよね?つまり、それは「Djangoのobject_list」の意味ですか?)。p = Paginator(thestuff, 7)p = Paginator(thestuff, 10)pp.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)よりも短くするために追加の名前付き引数を使用します。したがって、名目上の長さが10で、デルタファーストが3の単一のページネーターを使用して、最初のページ3を他のすべてのページよりも短くします。

(に問題がある可能性がありますが、validate_number表示されるかどうかはわかりません。問題が発生した場合は、MyPaginatorもそのメソッドをオーバーライドする必要があります)。

Djangoの最近のバージョンの更新

上記のコードは、位置引数を考慮していないためにエラーが発生しnum_pages、最後のページを正しく表示できるようにオーバーライドする必要があります。

from math import ceil


class MyPaginator(Paginator):
    
    def __init__(self, *args, **kw):
        self.deltafirst = kw.pop('deltafirst', 0)
        super().__init__(*args, **kw)
    
    def page(self, 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 self._get_page(self.object_list[bottom:top], number, self)

    @property
    def num_pages(self):
        if self.count == 0 and not self.allow_empty_first_page:
            return 0
        count = max(self.count - self.per_page + self.deltafirst, 0)
        hits = max(0, count - self.orphans)
        return 1 + ceil(hits / self.per_page)
于 2009-06-28T14:45:36.730 に答える
1

object_list()関数は、Paginatorを使用してリストを分解します。したがって、チャンクの「サイズ」を変更すると(7対8)...表示されたとおりに実行されます。

選択肢: その最後の選択肢は不安定です。そうしないでください:-)「ハックする」か、Paginatorに移動してください。

それをハックしてください...リクエスト>ページ1で、row_listに何か余分なものをこっそり入れてください。list(row_list)を介してリストに強制し、row_list.insert(0、None)を介してNoneまたは何かを追加できると思います。

Paginate ...Paginatorを使用する

ビュー+テンプレート...ビューにクエリセットrow_listをテンプレートに渡すだけです。テンプレートに1ページ目を確認してもらいます。そこにrow_listのサブセットのループ/表示を所有していますか。テンプレートにそのようなロジックがあるのは厄介です。複雑なテンプレートになります。

于 2009-06-28T16:13:31.810 に答える
0

これは古い質問だと思いますが、私のような誰かがここに来て、これを見つけた場合に備えて、私の単体テストで問題が発見されました。

_get_num_pagesAlexは基本的に正しいですが、を実装することも忘れない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)

そしてユニットテスト:

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])
于 2012-12-07T14:42:46.353 に答える
0

私の特定のシナリオでは、1つのレンダリングされたテンプレート内でオブジェクトをページ付けすることを検討していました(複数ページのドキュメントを作成します)。私の場合、最も簡単なアプローチは、ページネーターを忘れて、代わりにジェネレーターを使用することだと思います。

    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 }ページコンテキストに追加すると、可変ページャーが作成されます。num_recordsこれはpage_numberを受け取る関数であるため、究極の柔軟性が得られることに注意してください。

テンプレートでは、これをpaginatorと同じように扱うことができます。

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

  {% for obj in page.object_list %}
    {{ obj }}
  {% endfor %}
{% endfor %}
于 2013-06-06T03:11:52.827 に答える