2009-04-14 5 views
9

Ich entwickle gerade eine Django-Anwendung, die die berüchtigte "Paginierung" -Technik verwenden wird. Ich versuche herauszufinden, wie das Modul django.core.paginator funktioniert.Django Paginierung und "aktuelle Seite"

Ich habe eine Anwendung mit einem Frage-Modell. Ich werde alle Fragen mit diesem Paginator auflisten. Es wird 20 Fragen pro Seite geben.

def show_question(question_pk): 
    questions = Question.objects.all() 
    paginator = Paginator(questions, 20) 
    page  = ... # Somehow figure out which page the question is on 
    return render_to_response('show_question.html', { 'page' : page }) 

In der Ansicht, wo ich die verschiedenen Seiten auflisten, wie "... 2, 3, 4 , 5, 6, ..." ich irgendwie die aktuelle Seite hervorheben möchte, wie viele Seiten machen.

Es gibt wirklich zwei Dinge, die ich wissen will:

  1. Wie mache ich Django herauszufinden, welche Seite die Frage an ist?
  2. Wie würde ich meine Vorlage schreiben, um die aktuell besuchte Seite richtig zu "markieren"?

EDIT: Sorry, ich habe einen Teil dieser Frage vergessen. Ich möchte auch, dass jede Seite außer der aktuellen eine Verbindung zu /questions/{{ that_page.start_index }} ist. Im Grunde würde jeder Link auf die erste Frage auf dieser Seite verlinken.

+0

Was meinen Sie bei jeder Seite außer der aktuellen wollen auf dieser Seite auf die Frage zu verknüpfen? Wie wird der Benutzer jemals die Seiten wechseln? –

+0

Ich möchte keine übergeben? Seite = 4 GET Request Parameter oder irgendetwas. Ich werde nur/question/4 für Frage 4 verwenden, und dann wird die Ansicht herausfinden, auf welcher Seite diese Frage steht. Deshalb sind die Seitenlinks wirklich auf Fragen gerichtet. –

+0

Würde sich die erste Frage auf einer Seite nicht ändern, wenn mehr Fragen hinzugefügt oder möglicherweise sortiert werden? Aus einer REST/HTTP-Perspektive bedeutet dies, dass die URL nicht auf eine echte Ressource verweist. Aus diesem Grund verwendet Django einen GET-Parameter, um die Anzeigeeigenschaften der Ressource, die die URL identifiziert, zu kommentieren. –

Antwort

7

Hmm ... Ich sehe aus Ihrem Kommentar, dass Sie nicht den ol 'GET-Parameter machen wollen, was django.core.paginator für die Verwendung geschrieben wurde. Um zu tun, was Sie wollen, kann ich mir keinen besseren Weg vorstellen, als die Seite vorauszuberechnen, auf der sich jede Frage befindet. Als Beispiel wird Ihre Ansicht ist so etwas wie am Ende:

ITEMS_PER_PAGE = 20 
def show_question(question_pk): 
    questions = Question.objects.all() 
    for index, question in enumerate(questions): 
     question.page = ((index - 1)/ITEMS_PER_PAGE) + 1 
    paginator = Paginator(questions, ITEMS_PER_PAGE) 
    page = paginator.page(questions.get(pk=question_pk).page) 
    return render_to_response('show_question.html', { 'page' : page }) 

Um die aktuelle Seite in der Vorlage zu markieren, dann würden Sie so etwas wie

{% for i in page.paginator.page_range %} 
    {% ifequal i page.number %} 
     <!-- Do something special for this page --> 
    {% else %} 
     <!-- All the other pages --> 
    {% endifequal %} 
{% endfor %} 

wie für die Elemente tun, werden Sie habe zwei verschiedene object_lists mit denen man arbeiten kann ...

page.object_list 

werden die Objekte in der aktuellen Seite und

page.paginator.object_list 

werden alle Objekte, unabhängig von Seite sein. Jedes dieser Elemente wird eine "Seiten" -Variable haben, die Ihnen sagen wird, auf welcher Seite sie sich befinden.

Das alles gesagt, was Sie tun, klingt unkonventionell. Vielleicht möchten Sie umdenken, aber so oder so, viel Glück.

+0

Oh Junge, oh Junge! 'page.paginator.object_list [i] .page' klingt, als ob es genau das ist, wonach ich gesucht habe! Ich werde das sofort überprüfen. Vielen Dank! –

5

django-pagination sollte tun, was Sie wollen und kommt verpackt in einem hübschen Paket, das Sie einfach einstecken und verwenden können. Es verschiebt den Code im Wesentlichen von Ihren Ansichten zu den Vorlagen und einer Middleware.

EDIT: Ich habe gerade Ihre Bearbeitung gesehen. Sie können die aktuellen Objekte auf einer Seite mit {% autopaginate object_list %} abrufen, die object_list durch die aktuellen Objekte für eine bestimmte Seite ersetzt. Sie können es durchlaufen, und wenn Sie das erste wollen, sollten Sie in der Lage sein, es wie eine Liste zu behandeln und tun Sie object_list[0].

Wenn Sie dies in Ihrer Ansichten halten möchten, können Sie etwas tun könnte:

def show_question(question_pk): 
    questions = Question.objects.all() 
    paginator = Paginator(questions, 20) 
    return render_to_response('show_question.html', { 'page' : paginator }) 

Innerhalb Ihrer Vorlage können Sie die aktuelle Seite, die Sie sind zugreifen, indem Sie:

# Gives you the starting index for that page. 
# For example, 5 objects, and you're on the second page. 
# start_index will be 3. 
page.start_index 

# You can access the current page number with: 
# 1-based index 
page.number 

Damit sollten Sie in der Lage sein, alles zu tun, was Sie brauchen. Es gibt ein paar gute Beispiele here.

+0

Danke für Ihren Kommentar. Für mich scheint es jedoch so zu sein, dass die Django-Paginierung nicht mehr tut als das eingebaute Paginierungskram, sondern einfach die Logik vom Code in die Templates und eine Middleware verschiebt. Ist es so? –

+0

Im Wesentlichen ja. Ich habe meine Antwort aktualisiert, wenn Sie den Seitenumbruch in Ihrer Ansicht beibehalten möchten. –

10

Django, at least von Version 1.2, ermöglicht es uns, diese Aufgabe mit reinen Standard-Seitenumbruch-Vorlagen-Tags zu vervollständigen.

{% for page in article_list.paginator.page_range %} 
    {% if page == article_list.number %} 
    {{ page }} 
    {% else %} 
    <a href="/page{{ page }}">{{ page }}</a> 
    {% endif %} 
{% endfor %} 

Wo article_list ist Instanz von

paginator = Paginator(article_list, 20) 
    try: 
     article_list = paginator.page(int(page)) 
    except (EmptyPage, InvalidPage): 
     article_list = paginator.page(paginator.num_pages) 
+0

+1 wunderbar ... ist es möglich, Stackoverflow wie Paginierung zu schreiben (zB: 'prev 1 ... 7 8 9 10 11 ... 500435 next'). Ich meine die "..." – suhailvs

+0

@suhail, ja, es ist möglich, es zu tun, ändern Sie einfach die Vorlage mit [Django Vorlagensyntax] (https://docs.djangoproject.com/en/dev/ref/templates/builtins /). Aber ich würde Ihnen eher empfehlen, [django-endless-pagination] (http://django-endless-pagination.readthedocs.org/en/latest/) zu testen. Es ist einfach einzurichten und hat Standardeinstellungen für alle Arten von Paginierungsstilen. –