2010-02-06 13 views
14

Mam dość proste zapytanie zestawu oraz związanych z nimi poglądy Generic:następne poprzednie linki z zestawu zapytań/widoki generyczne

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,), 
) 

Tylko szablon dla generowania strony szczegółowości zdjęciu: więc nie ma widoku.


Czy istnieje łatwy sposób na link do poprzedniego | następny element szablonu bez ręcznego kodowania widoku?

Somthing jak:

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

Mmh co chcesz wiedzieć? Tak, możliwe jest, że już dostarczyłeś rozwiązanie. Trzeba tylko zaimplementować metodę 'next_item'. –

+2

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

+0

Widziałeś: jeśli to poddam Cóż, chodzi o to, że w modelu mam DateField lub DateTimeField, co nie jest moim przypadkiem: Chciałbym zamówić mój wynik zapytania przez (powiedzmy) pole id. Czy istnieje wstępnie skonfigurowany sposób przechodzenia przez zestaw wyników i uzyskania poprzedniego | następne przedmioty? Czy powinienem zaprojektować własne widoki i zakodować funkcję _get_ (next | previous) _item? – eaman

Odpowiedz

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 

można dostosować je do swoich potrzeb. Po prostu spojrzałam na twoje pytanie jeszcze raz ... żeby było łatwiejsze niż posiadanie instrukcji if, możesz spowodować, że metody zwrócą znacznik dla łącza do następnego/prev jeśli istnieje, w przeciwnym razie nic nie zwrócą. to po prostu robisz foto.get_next itd. Pamiętaj również, że kwerendy są leniwy, więc nie otrzymujesz ton elementów w następnym/prev.

+0

Dzięki, właśnie nad tym pracowałem: niestandardowa metoda dla mojego modelu dla następnych/prev linków. Dzięki za przykład, te (id__gt | lt = self.id) wyglądają znacznie lepiej niż to, o czym myślałem. Bardzo doceniane. – eaman

+0

'get_prev' i' get_next' zwracają obiekty, więc musiałem użyć 'foto.get_next.id', aby uzyskać pk następnego/prev. Dzięki! – curtisp

+0

Dzięki, przy okazji. nie ma potrzeby sprawdzania, czy 'next' i' pref'. 'first()' zwraca 'None', jeśli nic nie znaleziono – MartinM

1

Jeśli zaakceptujesz Model.objects.all() jako zestaw zapytań, a ty będziesz w stanie zdobyć następne/poprzednie pozycje według pola daty (zwykle pole 'created' z auto_now_add = True da taką samą kolejność jako id obiektu), można użyć get_next_by_foo() and get_previous_by_foo(), gdzie "foo" jest polem daty.

Dla następnych/poprzednich linków z bardziej skomplikowanego QuerySet, użycie Paginator with threshold set to one wydaje się być najlepszą opcją.

7

Foto wersja powyżej ma kilka niedociągnięć:

  • robi logiczną ocenę jak if next: może być powolne, ponieważ w zasadzie ładuje całą QuerySet wynik. Użyj next.exists() lub try/except jak w mojej wersji.
  • Wynik get_prev() jest nieprawidłowy, ponieważ w tym przypadku trzeba odwrócić kolejność.

FWIW Więc oto moja wersja, która jest dla rodzajowego klucza podstawowego:

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 
Powiązane problemy