2011-01-04 8 views
1

Ich habe eine Frage darüber, wie Django Paginator-Modul funktioniert und wie Sie es optimieren. Ich habe eine Liste von etwa 300 Artikeln aus Informationen, die ich von verschiedenen APIs im Internet bekomme. Ich benutze Djangos Paginator-Modul, um die Liste für meine Besucher, 10 Artikel gleichzeitig, anzuzeigen. Die Seitennummerierung funktioniert nicht so gut, wie ich es möchte. Es scheint, dass der Paginator alle 300 Elemente erhalten muss, bevor er die zehn herauszieht, die jedes Mal angezeigt werden müssen, wenn die Seite geändert wird. Wenn beispielsweise 30 Seiten vorhanden sind, muss die Website auf Seite 2 erneut die APIs abfragen, alle Informationen in eine Liste aufnehmen und dann auf die zehn Seiten zugreifen, die der Browser des Besuchers anfordert. Ich möchte nicht die APIs für die gleichen Informationen abfragen, die ich bereits auf jeder Seite habe.Wie für Django Paginator-Modul zu optimieren

Im Moment hat meine Ansichten eine Funktion, die die get-Anfrage untersucht und die APIs nach Informationen auf der Grundlage der Abfrage abfragt. Dann fügt es all diese Informationen in eine Liste ein und übergibt sie an die Vorlagendatei. Diese Funktion wird also immer geladen, wenn jemand die Seite umschaltet und die APIs erneut abfragt.

Wie soll ich das beheben?

Vielen Dank für Ihre Hilfe.

Antwort

1

Der Paginator benötigt in diesem Fall die vollständige Liste, um seine Aufgabe zu erfüllen.

Mein Rat wäre, einen Cache der Feeds in regelmäßigen Abständen zu aktualisieren und diesen Cache dann als Eingabe für das Paginator-Modul zu verwenden. Es ist immer eine schlechte Idee, eine intensive oder langwierige Aufgabe für jede Anfrage zu erledigen. Wenn Sie die Ladezeiten der Seite nicht bemerken, denken Sie an die Sicherheitsanfälligkeit Ihres Servers.

Sie möchten möglicherweise Django's low level cache API auschecken, die es Ihnen ermöglichen würde, das Feedergebnis an einem global zugänglichen Ort unter einem Schlüssel zu speichern, den Sie später zum Abrufen des Caches und Paginates für jede Seitenanforderung verwenden können.

+2

Nur um eine Klarstellung hinzuzufügen, wenn Sie Elemente gerade von der Datenbank über das Django ORM erhalten, fragt der Paginator richtig nur nach den Einzelteilen ab, die er benötigt, und zählt einfach, um die Summen zu erhalten. Aber wenn Sie die Daten von anderswo bekommen, wird es in der Tat alles an erster Stelle bekommen müssen. –

0

ORM keine Daten geladen werden, bis die Zeile ausgewählt ist:

query_results = Foo(id=1) # No sql executed yet, just stored. 

foo = query_results[0] # now it fires 

oder

for foo in query_results: 
    foo.bar() # sql fires 

Wenn Sie eine benutzerdefinierte Datenquelle verwenden, die Ergebnisse bei der Initialisierung dann die Paginierung wird geladen wird nicht funktionieren wie erwartet, da alle Feeds sofort abgerufen werden. Sie können die Unterklasse __getitem__ oder __iter__ ableiten, um den tatsächlichen Abruf durchzuführen. Es stimmt dann mit der Art überein, wie Django erwartet, dass die Ergebnisse geladen werden.

Die Seitennummerierung muss wissen, wie viele Ergebnisse es gibt, um Dinge wie has_next() zu tun. In SQL ist es normalerweise preiswert, einen count(*) mit einem Index zu erhalten. Sie möchten also auch wissen, wie viele Ergebnisse es gibt (oder vielleicht nur schätzen, wenn es zu teuer ist, genau zu wissen).