2013-07-31 14 views
7

Non riesco a raggiungere la 'pagina precedente' nel paging ndb.Come passare alla pagina precedente con i cursori ndb?

Ho verificato il documentation e anche questo simile question here senza successo.

def show_feedback(kind, bookmark=None): 
    """Renders returned feedback.""" 
    cursor = None  
    more_p= None 
    if bookmark: 
     cursor = Cursor(urlsafe=bookmark) 

    q = Feedback.query() 
    q_forward = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(-Feedback.pub_date) 
    q_reverse = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(Feedback.pub_date) 

    feedbacks, next_cursor, more = q_forward.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=cursor) 
    if cursor: 
     rev_cursor = cursor.reversed() 
     feedbacks2, prev_cursor, more_p = q_reverse.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=rev_cursor) 

    next_bookmark = None 
    prev_bookmark = None 
    if more and next_cursor: 
     next_bookmark = next_cursor.urlsafe() 
    if more_p and prev_cursor: 
     prev_bookmark = prev_cursor.urlsafe() 
    return render_template_f11('show_feedback.html', kind=kind, feedbacks=feedbacks, next_bookmark=next_bookmark, prev_bookmark=prev_bookmark) 

html:

{% if prev_bookmark %} 
     <a href="{{ url_for(request.endpoint, bookmark=prev_bookmark) }}">Previous</a> 
    {% endif %} 
    {% if next_bookmark %} 
    <a href="{{ url_for(request.endpoint, bookmark=next_bookmark) }}">Next</a> 
    {% endif %} 

posso pagina avanti correttamente fino alla fine. Ma non posso retrocedere fino all'ultima pagina e anche allora non posso tornare indietro fino alla prima pagina.

Cosa mi manca, per favore?

UPDATE:

codice modificato con i suggerimenti di Faisal. Funziona meglio devo ammettere. Ma ancora il paging non funziona correttamente:

Ho 7 voci. PAGE_SIZE in config è 3. Quindi otteniamo tre pagine:

Quando si fa clic su Avanti, ottengo 7,6,5 -> 4,3,2 -> 1 Perfetto. Ora, quando si fa clic su precedenti: 1 -> 3,4,5 -> 5,6,7

Grazie per il vostro aiuto

def show_feedback(kind, bookmark=None): 
    """Renders returned feedback.""" 
    is_prev = request.args.get('prev', False) 
    cursor = None   
    if bookmark: 
     cursor = Cursor(urlsafe=bookmark) 

    q = Feedback.query() 
    q_forward = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(-Feedback.pub_date) 
    q_reverse = q.filter(Feedback.kind==Feedback.KINDS[kind]).order(Feedback.pub_date) 

    qry = q_reverse if is_prev else q_forward 

    feedbacks, cursor, more = qry.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=cursor) 

    if is_prev: 
     prev_bookmark = cursor.reversed().urlsafe() if more else None 
     next_bookmark = bookmark 
    else: 
     prev_bookmark = bookmark 
     next_bookmark = cursor.urlsafe() if more else None 
    return render_template_f11('show_feedback.html', kind=kind, feedbacks=feedbacks, next_bookmark=next_bookmark, prev_bookmark=prev_bookmark) 

UPDATE 2 (?):

(?)

Sembra che ora funzioni quasi con reverse().

7,6,5 -> accanto -> 4,3,2 -> accanto -> 1

1 -> prev -> 2,3,4 -> 5,6,7 (ordine è no longr latest date first)

+0

hai preso il problema ordinazione capito? Sto anche facendo l'ordine delle date e lo schema nel pasticcio dei documenti. –

risposta

9

Quindi quello che faccio qui è utilizzare il segnalibro corrente per navigare per il prossimo o precedente e rimuovere l'altra query in modo che non esegua query due volte per ogni richiesta. (La vecchia descrizione/risposta era sbagliata quando l'ho testata, questa funziona sul mio localhost).

Prova:

is_prev = self.request.get('prev', False) 
if is_prev: 
    qry = q_reverse 
    cursor = cursor.reversed() 
else: 
    qry = q_forward 

feedbacks, cursor, more = qry.fetch_page(app.config['FEEDBACK_PER_PAGE'], start_cursor=cursor) 

if is_prev: 
    prev_bookmark = cursor.reversed().urlsafe() if more else None 
    next_bookmark = bookmark 
else: 
    prev_bookmark = bookmark 
    next_bookmark = cursor.urlsafe() if more else None 

html

{% if prev_bookmark %} 
    <a href="{{ url_for(request.endpoint, bookmark=prev_bookmark, prev=True) }}">Previous</a> 
{% endif %} 
{% if next_bookmark %} 
    <a href="{{ url_for(request.endpoint, bookmark=next_bookmark) }}">Next</a> 
{% endif %} 
+0

Faisal, grazie mille per il vostro aiuto in merito.Ora ho pubblicato il codice aggiornato e il risultato. Funziona meglio di prima, tuttavia i passaggi precedenti non sono ancora corretti. Così strano ... – Houman

+0

ha aggiornato la risposta, ho aggiunto il cursore.reverso() quando is_prev penso che sia quello che mi mancava. – Faisal

+0

Sì, Faisal, ha quasi risolto il problema. Abbastanza complicato. Ma l'ordine non è ancora completamente corretto. Si prega di consultare la domanda aggiornata. Grazie, – Houman

0

Ecco una soluzione di lavoro completa. C'è qualcosa di sbagliato nel tuo codice.

La chiave è l'inversione dei risultati quando si va indietro. È difficile.

Qui si ha:

def return_query_page(query_class, size=10, bookmark=None, is_prev=None, equality_filters=None, orders=None): 
    """ 
    Generate a paginated result on any class 
    Param query_class: The ndb model class to query 
    Param size: The size of the results 
    Param bokkmark: The urlsafe cursor of the previous queries. First time will be None 
    Param is_prev: If your requesting for a next result or the previous ones 
    Param equal_filters: a dictionary of {'property': value} to apply equality filters only 
    Param orders: a dictionary of {'property': '-' or ''} to order the results like .order(cls.property) 
    Return: a tuple (list of results, Previous cursor bookmark, Next cursor bookmark) 
    """ 
    if bookmark: 
     cursor = ndb.Cursor(urlsafe=bookmark) 
    else: 
     is_prev = None 
     cursor = None 

    q = query_class.query() 
    try: 
     for prop, value in equality_filters.iteritems(): 
      q = q.filter(getattr(query_class, prop) == value) 

     q_forward = q.filter() 
     q_reverse = q.filter() 

     for prop, value in orders.iteritems(): 
      if value == '-': 
       q_forward = q_forward.order(-getattr(query_class, prop)) 
       q_reverse = q_reverse.order(getattr(query_class, prop)) 
      else: 
       q_forward = q_forward.order(getattr(query_class, prop)) 
       q_reverse = q_reverse.order(-getattr(query_class, prop)) 
    except: 
     return None, None, None 
    if is_prev: 
     qry = q_reverse 
     new_cursor = cursor.reversed() if cursor else None 
    else: 
     qry = q_forward 
     new_cursor = cursor if cursor else None 

    results, new_cursor, more = qry.fetch_page(size, start_cursor=new_cursor) 
    if more and new_cursor: 
     more = True 
    else: 
     more = False 

    if is_prev: 
     prev_bookmark = new_cursor.reversed().urlsafe() if more else None 
     next_bookmark = bookmark 
     results.reverse() 
    else: 
     prev_bookmark = bookmark 
     next_bookmark = new_cursor.urlsafe() if more else None 

    return results, prev_bookmark, next_bookmark 

Questo è il link al progetto GitHub: https://github.com/janscas/ndb-gae-pagination

+1

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. –

+0

Cambiato in modo da visualizzare il codice corrente. – janscas

Problemi correlati