2010-02-06 3 views
14

Ich habe eine ziemlich einfache Abfrage gesetzt und eine damit verbundene allgemeine Ansichten:nächste vorherige Links von einer Abfrage/generic Ansichten

f_detail = { 
     'queryset': Foto.objects.all(), 
     'template_name': 'foto_dettaglio.html', 
     "template_object_name" : "foto", 
     } 

urlpatterns = patterns('', 
# This very include 
(r'^foto/(?P<object_id>\d+)/$', list_detail.object_detail, f_detail,), 
) 

einfach eine Vorlage für eine Detailseite eines Fotos zu erzeugen: so gibt es keine Aussicht.


Gibt es eine einfache Möglichkeit, eine Verknüpfung zu vorherigen | nächstes Element in der Vorlage ohne manuelle Codierung einer Ansicht?

Somthing wie a:

{% if foto.next_item %} 
    <a href="/path/foto/{{ foto.next_item.id_field }}/">Next</a> 
{% endif} 
+0

Mmh was wollen Sie wissen? Ja, es ist möglich, dass Sie bereits die Lösung bereitgestellt haben. Sie müssen nur die Methode 'next_item' implementieren. –

+2

http://stackoverflow.com/questions/1931008/is-there-a-clever-way-to-get-the-previous-next-item-using-the-django-orm – shanyu

+0

Sah das: wenn ich es unterschritt Nun, es geht darum, ein DateField oder DateTimeField im Modell zu haben, was nicht mein Fall ist: Ich würde gerne mein queryset-Ergebnis nach (sagen wir mal) dem ID-Feld ordnen. Gibt es eine vorkonfigurierte Möglichkeit, die Ergebnismenge zu durchlaufen und die vorherige | zu erhalten nächste Artikel? Oder sollte ich meine eigenen Ansichten entwerfen und eine _get_ (next | previous) _item Funktion codieren? – eaman

Antwort

24
class Foto(model): 
    ... 
    def get_next(self): 
    next = Foto.objects.filter(id__gt=self.id) 
    if next: 
     return next.first() 
    return False 

    def get_prev(self): 
    prev = Foto.objects.filter(id__lt=self.id).order_by('-id') 
    if prev: 
     return prev.first() 
    return False 

können Sie diese nach Ihren Wünschen optimieren. Ich habe Ihre Frage noch einmal angeschaut ... um es einfacher zu machen als mit der if-Anweisung, könnten Sie die Methode veranlassen, das Markup für den Link zum nächsten/vorherigen zurückzugeben, wenn es einen gibt, andernfalls geben Sie nichts zurück. dann würdest du einfach foto.get_next usw. machen. auch daran erinnern, dass die abfragesätze faul sind also du nicht wirklich tonnen von einzelteilen in next/prev bekommst.

+0

Danke, daran habe ich gerade gearbeitet: eine benutzerdefinierte Methode für mein Modell für die nächsten/vorherigen Links. Danke für das Beispiel, diese (id__gt | lt = self.id) sehen viel besser aus als das, woran ich gedacht habe. Sehr geschätzt. – eaman

+0

'get_prev' und' get_next' return objects also musste 'foto.get_next.id' verwendet werden, um den pk von next/prev zu erhalten. Vielen Dank! – curtisp

+0

Danke, übrigens. es gibt keine Notwendigkeit zu überprüfen, ob "next" und "pref". 'first()' gibt 'None' zurück, wenn nichts gefunden wird – MartinM

1

Wenn Sie Model.objects.all() als Ihr Abfragesatz akzeptieren, und Sie sind in Ordnung, wenn Sie nächste/vorherige Elemente nach einem Datumsfeld greifen (normalerweise wird ein Feld mit "created" mit auto_now_add = True die gleiche Reihenfolge erhalten) Als Objekt-ID können Sie get_next_by_foo() and get_previous_by_foo() verwenden, wobei 'foo' das Datumsfeld ist.

Für nächste/vorherige Links von einem komplizierteren QuerySet, mit der Paginator with threshold set to one scheint es könnte die beste Option sein.

7

Die Foto Version hat oben ein paar Mängel:

  • eine boolean Auswertung wie if next: tun kann langsam sein, da es im Grunde das gesamte QuerySet Ergebnis belastet. Verwenden Sie next.exists() oder das try/except wie in meiner Version.
  • Das Ergebnis get_prev() ist falsch, da Sie in diesem Fall die Reihenfolge umkehren müssen.

So FWIW hier ist meine Version, die für eine generische Primärschlüssel ist:

def get_next(self): 
    """ 
    Get the next object by primary key order 
    """ 
    next = self.__class__.objects.filter(pk__gt=self.pk) 
    try: 
     return next[0] 
    except IndexError: 
     return False 

def get_prev(self): 
    """ 
    Get the previous object by primary key order 
    """ 
    prev = self.__class__.objects.filter(pk__lt=self.pk).order_by('-pk') 
    try: 
     return prev[0] 
    except IndexError: 
     return False 
Verwandte Themen