2010-02-06 10 views
14

ho un bel semplice query set ed un relativo viste generiche:Avanti precedenti collegamenti da una serie di query/viste generiche

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

Basta un modello per la generazione di una pagina di dettaglio di una foto: quindi non c'è vista.


C'è un modo semplice per avere un collegamento al precedente | elemento successivo nel modello senza la codifica manuale di una vista?

Somthing come un:

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

Mmh cosa vuoi sapere? Sì, è possibile che tu abbia già fornito la soluzione. Devi solo implementare il metodo 'next_item'. –

+2

http://stackoverflow.com/questions/1931008/is-there-a-verno-del-punto-del-previous-next-item-using-the-django-orm – shanyu

+0

Visto che: se lo sottolo beh, si tratta di avere un DateField o DateTimeField nel modello, che non è il mio caso: vorrei ordinare il risultato del mio queryset per (diciamo) il campo id. C'è un modo preconfigurato per attraversare il set di risultati e ottenere precedente | articoli successivi? O dovrei progettare le mie viste e codificare una funzione _get_ (successiva | precedente) _item? – eaman

risposta

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 

è possibile modificare questi a proprio piacimento. ho appena guardato di nuovo la tua domanda ... per rendere più semplice l'istruzione if, potresti fare in modo che i metodi restituiscano il markup per il link al prossimo/prev se ce n'è uno, altrimenti non restituire nulla. allora devi semplicemente fare foto.get_next, ecc. Ricorda anche che i set di query sono pigri, quindi in realtà non stai ricevendo tonnellate di elementi in next/prev.

+0

Grazie, è quello su cui stavo lavorando in questo momento: un metodo personalizzato per il mio modello per i link next/prev. Grazie per l'esempio, questi (id__gt | lt = self.id) sembrano molto meglio di quello che stavo pensando. Molto apprezzato. – eaman

+0

Gli oggetti restituiti 'get_prev' e' get_next' hanno dovuto usare 'foto.get_next.id' per ottenere il pk di next/prev. Grazie! – curtisp

+0

Grazie, btw. non è necessario controllare se 'next' e' pref'. 'first()' restituisce 'None' se non è stato trovato nulla – MartinM

1

Se si accetta Model.objects.all() come queryset e si sta accettando l'acquisizione degli elementi successivo/precedente in base a un campo data (in genere un campo 'creato' con auto_now_add = True darà lo stesso ordine come ID oggetto), è possibile utilizzare get_next_by_foo() and get_previous_by_foo(), dove 'foo' è il campo della data.

Per i collegamenti precedenti/precedenti da un QuerySet più complesso, l'utilizzo di Paginator with threshold set to one sembra essere l'opzione migliore.

7

La versione Foto sopra ha un paio di difetti:

  • Facendo una valutazione booleana come if next: può essere lento in quanto carica praticamente l'intero QuerySet risultato. Utilizzare next.exists() o provare/tranne come nella mia versione.
  • Il risultato get_prev() è errato perché in questo caso è necessario invertire l'ordine.

Quindi FWIW ecco la mia versione, che sia per una chiave primaria generico:

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 
Problemi correlati