2015-06-18 2 views
18

Sto utilizzando lo strumento integrato di Django pagination per impaginare i dati e visualizzarli nel modello. Ora vorrei implementare jQuery per caricare e aggiungere pagine al modello usando ajax. Come lo faccio usando jQuery?Come aggiungere pagine di dati usando l'impaginazione jQuery e Django?

Stavo usando django-endless-pagination prima, ma poiché aggiunge le voci di JavaScript il mio lightbox per visualizzare le immagini non cattura gli elementi dell'immagine e visualizza solo la voce che è stata caricata alla prima richiesta.

views.py:

def snaps(request): 
    snapgroup_list = SnapGroup.objects.all() 
    paginator = Paginator(snapgroup_list, 1) 

    try: 
     page = int(request.GET.get('page', '1')) 
    except: 
     page = 1 
    try: 
     snapgroup = paginator.page(page) 
    except(EmptyPage, InvalidPage): 
     snapgroup = paginator.page(page) 

    index = snapgroup.number - 1 # edited to something easier without index 
    max_index = len(paginator.page_range) 
    start_index = index - 3 if index >= 3 else 0 
    end_index = index + 3 if index <= max_index - 3 else max_index 
    page_range = paginator.page_range[start_index:end_index] 

    return render(request, 'snaps.html', { 
     'page_range': page_range, 
     'snapgroup':snapgroup 
     }) 

snaps.html:

{% extends "base.html" %} 
{% block main_content %} 

<div id="main_content"> 
    <div id="snap_wrapper" class="container"> 
     <hr> 
     {% if snapgroup.object_list.count > 0 %} 
      {% include 'snapgroups.html' %} 
     {% else %} 
      <li><p>No SNAPS yet!</p></li> 
      <span class="clear_both"></span> 
     {% endif %} 
    </div> 

</div> 
<div class="container"> 
    <div class="prev_next"> 
     {% if snapgroup.has_previous %} 
      <a class="prev btn btn-info" href="?page={{snapgroup.previous_page_number}}">Prev</a> 
     {% endif %} 
     {% if snapgroup.has_next %} 
      <a class="next btn btn-info" href="?page={{snapgroup.next_page_number}}">Next</a> 
     {% endif %} 
     <div class="pages"> 
      <ul> 
      {% for pg in page_range %} 
      {% if snapgroup.number == pg %} 
       <li><a href="?page={{pg}}" class="btn btn-default">{{pg}}</a></li> 
      {% else %} 
       <li><a href="?page={{pg}}" class="btn">{{pg}}</a></li> 
      {% endif %} 
      {% endfor %} 
      </ul> 
     </div> 
     <span class="clear_both"></span> 
    </div> 
</div> 

{% endblock %} 

snapgroups.html:

{% for sg in snapgroup.object_list %} 
    <h4 id="combination" class="snap_date">{{sg.date|date:'l'}}, {{sg.date}}</h4> 
    <ul> 
    {% for snap in sg.snap_set.all %} 
     <li><a href="{{MEDIA_URL}}{{snap.image}}" data-imagelightbox="f"><img src="{{MEDIA_URL}}{{snap.image}}" alt="{{snap.caption}}" /></a></li> 
    {% endfor %} 
     <span class="clear_both"></span> 
    </ul> 
{% endfor %} 
+0

personalmente non vorrei utilizzare l'impaginazione di Django, se si desidera utilizzare Ajax. Ci sono molti cercapersone JavaScript che funzionano molto bene con i dati JSON inviati dal server Django. Oppure, se si volesse, si potrebbe usare Django-Rest-Framework che ha anche una paginazione integrata, ma sarebbe molto più efficiente colpire gli endpoint tramite ajax. –

+0

@ChrisHawkes Sì, sarebbe meglio. Ma sto solo imparando, potresti per favore mostrarmi come farlo. Va bene se dovessi cambiare il codice se ottengo il risultato che voglio. – Robin

risposta

3

sarò ancora utilizzare django-endless-pagination (suo il migliore impaginazione basato Ajax plug-là fuori), e la soluzione per il problema sarebbe essere quello di ricordare la lightbox init dopo la richiesta impaginazione completato, saperne di più su callbacks:

<script type="text/javascript"> 
    function hookup_lightbox(){ 
     $(selector).imageLightbox(); 
    } 

    $.endlessPaginate({ 
     onCompleted: function(context, fragment) { 
      // hookup lightbox 
      hookup_lightbox(); 
     } 
    }); 
</script> 
+0

questa soluzione è la risposta adatta meglio alla domanda originale. (Anche se suggerirei una soluzione usando Django Rest Framework come già menzionato @ChrisHawkes) –

6

avrei mostrerò con un esempio app. Dal momento che stai imparando, questo ti sarà utile se effettivamente realizzi una di queste app con il codice qui sotto.

Ho provato a mantenere il codice il minimo possibile.

models.py

class Article(...): 
    title = models.CharField(...) 
    photo = models.ImageField(...) 

views.py

import json 

def article_ajax(request): 
    TOTAL = 10 
    OFFSET = request.GET.get('offset', 0) 
    END = offset + TOTAL 
    # TOTAL means how many articles to load 
    # in a single request 

    # to understand OFFSET and END, consider this: 
    # mylist = [1,2,3,4,5,6,7,8,9] 
    # mylist[2:5] outputs => [3,4,5] 
    # Above 2 is OFFSET and 5 is END 

    articles = Article.objects.all()[OFFSET:END] 

    json_list = [] 
    for article in articles: 
     json_list.append({ 
      'title': article.title, 'photo_url': article.photo.url 
     }) 

    data = json.dumps(json_list) 

    return HttpResponse(data, content_type='application/json') 

urls.py

... 
url(r'^ajax/articles/$', 'myapp.views.article_ajax'), 
... 

articles.html

Lo script contiene anche il codice scrolling infinito, troppo :)

<!-- All articles will be loaded in following div --> 
<div id="ArticlesDiv"></div> 

<script> 
var articleOffset = 0; 

var articleLoader = function() { 
    $.ajax({ 
     url: '/ajax/articles/?offset=' + articleOffset, 
     success: function(data) { 
      if (data.length > 0) { 
       for (var i = 0, total = data.length; i < total; i++) { 
        var compile_data; 
        compile_data = '<h1>' + data[i].title + '</h1>\ 
         <img src="' + data[i]photo_url + '">'; 

        $('#ArticlesDiv').append(compile_data); 
       } 

       /* update the offset */ 
       articleOffset += 10 
      } else { 
       $('#ArticlesDiv').append('No articles found'); 
      } 
     } 
    }); 
} 

/* Infinite scrolling for fetching articles */ 
var $window = $(window); 
function prodScrollPosition() { 
    var distance = $window.scrollTop() + $window.height(); 
    if ($('body').height() <= distance && $('#ArticlesDiv')) { 
     articleLoader(); 
    } 
} 

$window.scroll(prodScrollPosition).scroll(); 

/* Manually initiate the first ajax request */ 
articleLoader(); 
</script> 
+0

Wow, questo è molto bello. Sono solo confuso su come farlo mentre faccio riferimento a una chiave esterna, con '_set.all'. Dato che nel modello sto facendo il giro di ogni 'SnapGroup' e poi di nuovo loop attraverso ogni' Snap' di uno 'SnapGroup'. Come lo faccio? Per favore mi aiuti con questo. Grazie. – Robin

+0

@Robin Non penso che sia una buona idea mostrare tutti gli 'SnapGroups' e tutti gli' Snap 'in una pagina. È troppo database e rallenterà l'applicazione se ci sono troppe righe nel database. Quello che consiglierei di fare è visualizzare tutti gli 'SnapGroups' in una pagina.Quindi l'utente sceglierà uno 'SnapGroup' per vedere gli' Snaps' in esso. Questo approccio è più veloce e non colpirà il database con query inutili. – xyres