Je weniger Informationen Sie für jede Anfrage an die Website übertragen müssen, desto besser. Weil wir weniger Last auf dem Server und auf dem Kommunikationskanal bekommen. Als erste derartige Verbesserung auf der Website habe ich das Laden der Artikelliste beim Navigieren durch den Seiten-Paginator vorgenommen.
Der Punkt ist, dass wenn ein Benutzer zur nächsten Seite mit einer Liste von Artikeln gehen möchte und auf einen Link im paginator klickt, das Klickereignis ist abgefangen, wird das Ereignis abgebrochen, aber eine AJAX-Anforderung mit der angeforderten Seitennummer an den Server gesendet. Wenn der Server eine solche Anfrage erhält, rendert er nur die Artikelliste und sendet sie zurück.
Ersetzen der URL im Browser ohne Neuladen der Seite
Für die Hauptseite der Website habe ich eine JavaScript-Datei index.js erstellt, die die AJAX-Anforderungslogik enthält und den Click-Handler an die Links im Paginator bindet. Der wichtige Punkt ist, dass ich django-bootstrap3 für den Paginator verwende. Um den Click-Handler zu verbinden, verwende ich dementsprechend den Selektor '.paginator > li > a' .
Der Inhalt der Datei sieht wie folgt aus
class Index { static initPaginator() { document.body.querySelectorAll('.pagination > li > a') .forEach( link => link.addEventListener('click', Index.pagination_link_clickHandler) ); } static pagination_link_clickHandler(event){ event.preventDefault(); // запрещаем событие let path = event.target.href; // забираем путь let page = Global.getURLParameter(path, 'page'); if (typeof page !== 'undefined') { jQuery.ajax({ url: jQuery(this).attr('action'), type: 'POST', data: {'page': getURLParameter(path, 'page')}, // забираем номер страницы, которую нужно отобразить success : function (json) { // Если запрос прошёл успешно и сайт вернул результат if (json.result) { window.history.pushState({route: path}, "EVILEG", path); // устанавливаем URL в строку браузера jQuery("#articles-list").replaceWith(articles); // Заменяем div со списком статей на новый Index.initPaginator(); // Переинициализируем пагинатор jQuery(window).scrollTop(0); // Скроллим страницу в начало } } }); } } } Index.initPaginator();
Ich versuche, den Ecmascript 6-Standard zu verwenden, daher wird für die Indexseite die Index-Klasse verwendet, um die angewandten Methoden zusammenzufassen.
Um die Seitennummer in der URL zu erhalten, verwenden Sie die Funktion getURLParameter .
Vorlagenstruktur
Daher sollten wir eine spezielle Vorlagenstruktur haben, nämlich eine Vorlage zum Rendern einer Artikelliste, in meinem Fall eine Vorlage mit einer Vorschau eines Artikels, sowie eine Vorlage für die Hauptseite der Website.
Das heißt, es wird sein:
- article_preview.html - wir werden diese Vorlage nicht berücksichtigen, da sie für uns in diesem Fall nicht interessant ist
-
article_previews_list.html
*index.html
index.html
index.html wird von der Basisvorlage base.html geerbt, die einen Block zum Einbinden von Javascript-Dateien enthält.
{% extends 'base.html' %} {% block page %} {% include 'article_previews_list.html' %} {% endblock %} {% block javascript_footer %} <script src="/static/js/index.js"></script> {% endblock %}
article_previews_list.html
Die Artikelliste ist ein div , das bei jeder Anfrage ersetzt wird.
<div id="articles-list"> {% load bootstrap_pagination from bootstrap3 %} {% for article in object_list %} {% include 'knowledge/article_preview.html' %} {% endfor %} {% bootstrap_pagination object_list pages_to_show="10" %} </div>
urls.py
Die Route für die Hauptseite sieht folgendermaßen aus
urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index') ]
views.py
Betrachten Sie nun eine Ansicht, die eine Liste von Artikeln oder die gesamte Seite auf einmal zurückgibt
class IndexView(View): template_name = 'index.html' def get(self, request): return render(request=request, template_name=self.template_name, context={'object_list': get_paginated_page(request, Article.objects.all())}) def post(self, request): if request.is_ajax(): return JsonResponse({ "result": True, "articles": render_to_string( request=request, template_name='article_previews_list.html', context={'object_list': get_paginated_page(request, Article.objects.all())} ) }) else: raise Http404()
Ein wichtiger Punkt ist, dass die Site beide Arten von Anfragen korrekt verarbeiten muss, sowohl reguläre als auch AJAX-Anfragen. Da kann der Benutzer sowohl direkt zu einer der Seiten gehen als auch die Paginierung auf der Website verwenden.
Sie könnten an der get_paginated_page -Methode in diesem Code interessiert sein, die mithilfe der Paginator-Klasse die gewünschte Seite zur Anzeige generiert.
# -*- coding: utf-8 -*- from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage def get_paginated_page(request, objects, number=10): current_page = Paginator(objects, number) page = request.GET.get('page') if request.method == 'GET' else request.POST.get('page') try: return current_page.page(page) except PageNotAnInteger: return current_page.page(1) except EmptyPage: return current_page.page(current_page.num_pages)
Für Django empfehle ich Timeweb-Hoster VDS-Server .
Евгений Здравствуйте! Не могу понять вот эту часть кода: url: jQuery(this).attr('action')
наверное здесь должен быть путь к url, тогда 'action' на какой url указывает?
Добрый день. Там будет url, на который указывает ссылка тега a в пагинаторе, если правильно помню )) Написал этот код и забыл.