Әрбір сұрау үшін сайтқа неғұрлым аз ақпарат жіберу керек болса, соғұрлым жақсы. Өйткені біз серверге және байланыс арнасына аз жүктеме аламыз. Сайттағы бірінші осындай жақсарту, мен бет пагинаторы арқылы шарлау кезінде мақалалар тізімін жүктеуді жасадым.
Мәселе мынада: пайдаланушы мақалалар тізімі бар келесі бетке өткісі келгенде және paginator сілтемесін басқанда, басу оқиғасы болады. ұсталса, оқиға жойылады, бірақ AJAX сұрауы сұралған бет нөмірімен серверге жіберіледі. Сервер мұндай сұрауды алғанда, ол мақалалар тізімін ғана көрсетеді және оны кері жібереді.
Браузердегі URL мекенжайын бетті қайта жүктемей ауыстыру
Сайттың негізгі беті үшін мен JavaScript index.js файлын жасадым, онда AJAX сұрауының логикасы, сондай-ақ пагинатордағы сілтемелердегі басу өңдеушісін байланыстыратын болады. Маңызды мәселе, мен пагинатор үшін django-bootstrap3 қолданамын. Сәйкесінше, басу өңдеушісін қосу үшін '.paginator > li > a' селекторын қолданамын.
Файлдың мазмұны келесідей болады
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();
Мен ecmascript 6 стандартын қолдануға тырысамын.Сондықтан, индекс беті үшін Index сыныбы қолданылған әдістерді қорытындылау үшін пайдаланылады.
URL мекенжайындағы бет нөмірін алу үшін getURLParameter функциясын пайдаланыңыз.
Үлгі құрылымы
Осылайша, бізде арнайы үлгі құрылымы болуы керек, атап айтқанда, мақалалар тізімін көрсетуге арналған үлгі болуы керек, менің жағдайда бір мақаланы алдын ала қарау үлгісі, сондай-ақ сайттың басты бетіне арналған үлгі болуы керек.
Яғни, бұл болады:
- article_preview.html - біз бұл үлгіні қарастырмаймыз, өйткені бұл жағдайда біз үшін қызық емес
- article_previews_list.html
- index.html
index.html
index.html JavaScript файлдарын қосу блогы бар base.html негізгі үлгісінен мұраланған.
{% 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
Мақалалар тізімі div болып табылады, ол әрбір сұраныс бойынша ауыстырылады.
<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
Негізгі бетке арналған маршрут келесідей болады
urlpatterns = [ url(r'^$', views.IndexView.as_view(), name='index') ]
рет көру.py
Енді мақалалар тізімін немесе бүкіл бетті бірден қайтаратын көріністі қарастырыңыз
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()
Маңызды мәселе - сайт сұраулардың екі түрін де, әдеттегі және AJAX сұрауларын да дұрыс өңдеуі керек. Өйткені пайдаланушы тікелей беттердің біріне де, сайттағы беттеуді де пайдалана алады.
Сізді осы кодтағы get_paginated_page әдісі қызықтыруы мүмкін, ол Paginator класын пайдаланып көрсету үшін қажетті бетті жасайды.
# -*- 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)
Django үшін Timeweb хостының VDS-сервері ұсынамын.
Евгений Здравствуйте! Не могу понять вот эту часть кода: url: jQuery(this).attr('action')
наверное здесь должен быть путь к url, тогда 'action' на какой url указывает?
Добрый день. Там будет url, на который указывает ссылка тега a в пагинаторе, если правильно помню )) Написал этот код и забыл.