Evgenii Legotckoi
Қаң. 8, 2018, 1:52 Т.Қ.

Django - 031-сабақ. Мазмұнды ішінара жүктеу арқылы бетті қайта жүктемей, URL мекенжайын өзгерту

Әрбір сұрау үшін сайтқа неғұрлым аз ақпарат жіберу керек болса, соғұрлым жақсы. Өйткені біз серверге және байланыс арнасына аз жүктеме аламыз. Сайттағы бірінші осындай жақсарту, мен бет пагинаторы арқылы шарлау кезінде мақалалар тізімін жүктеуді жасадым.

Мәселе мынада: пайдаланушы мақалалар тізімі бар келесі бетке өткісі келгенде және paginator сілтемесін басқанда, басу оқиғасы болады. ұсталса, оқиға жойылады, бірақ AJAX сұрауы сұралған бет нөмірімен серверге жіберіледі. Сервер мұндай сұрауды алғанда, ол мақалалар тізімін ғана көрсетеді және оны кері жібереді.


Браузердегі URL мекенжайын бетті қайта жүктемей ауыстыру

Сайттың негізгі беті үшін мен JavaScript index.js файлын жасадым, онда AJAX сұрауының логикасы, сондай-ақ пагинатордағы сілтемелердегі басу өңдеушісін байланыстыратын болады. Маңызды мәселе, мен пагинатор үшін django-bootstrap3 қолданамын. Сәйкесінше, басу өңдеушісін қосу үшін '.paginator > li > a' селекторын қолданамын.

Файлдың мазмұны келесідей болады

  1. class Index {
  2.  
  3. static initPaginator() {
  4. document.body.querySelectorAll('.pagination > li > a')
  5. .forEach( link => link.addEventListener('click', Index.pagination_link_clickHandler) );
  6. }
  7.  
  8. static pagination_link_clickHandler(event){
  9. event.preventDefault(); // запрещаем событие
  10.  
  11. let path = event.target.href; // забираем путь
  12. let page = Global.getURLParameter(path, 'page');
  13.  
  14. if (typeof page !== 'undefined') {
  15. jQuery.ajax({
  16. url: jQuery(this).attr('action'),
  17. type: 'POST',
  18. data: {'page': getURLParameter(path, 'page')}, // забираем номер страницы, которую нужно отобразить
  19.  
  20. success : function (json) {
  21.   // Если запрос прошёл успешно и сайт вернул результат
  22. if (json.result)
  23. {
  24. window.history.pushState({route: path}, "EVILEG", path); // устанавливаем URL в строку браузера
  25. jQuery("#articles-list").replaceWith(articles); // Заменяем div со списком статей на новый
  26. Index.initPaginator(); // Переинициализируем пагинатор
  27. jQuery(window).scrollTop(0); // Скроллим страницу в начало
  28. }
  29. }
  30. });
  31. }
  32. }
  33. }
  34.  
  35. Index.initPaginator();

Мен ecmascript 6 стандартын қолдануға тырысамын.Сондықтан, индекс беті үшін Index сыныбы қолданылған әдістерді қорытындылау үшін пайдаланылады.

URL мекенжайындағы бет нөмірін алу үшін getURLParameter функциясын пайдаланыңыз.

Үлгі құрылымы

Осылайша, бізде арнайы үлгі құрылымы болуы керек, атап айтқанда, мақалалар тізімін көрсетуге арналған үлгі болуы керек, менің жағдайда бір мақаланы алдын ала қарау үлгісі, сондай-ақ сайттың басты бетіне арналған үлгі болуы керек.

Яғни, бұл болады:

  • article_preview.html - біз бұл үлгіні қарастырмаймыз, өйткені бұл жағдайда біз үшін қызық емес
  • article_previews_list.html
  • index.html

index.html

index.html JavaScript файлдарын қосу блогы бар base.html негізгі үлгісінен мұраланған.

  1. {% extends 'base.html' %}
  2. {% block page %}
  3. {% include 'article_previews_list.html' %}
  4. {% endblock %}
  5. {% block javascript_footer %}
  6. <script src="/static/js/index.js"></script>
  7. {% endblock %}

article_previews_list.html

Мақалалар тізімі div болып табылады, ол әрбір сұраныс бойынша ауыстырылады.

  1. <div id="articles-list">
  2. {% load bootstrap_pagination from bootstrap3 %}
  3. {% for article in object_list %}
  4. {% include 'knowledge/article_preview.html' %}
  5. {% endfor %}
  6. {% bootstrap_pagination object_list pages_to_show="10" %}
  7. </div>

urls.py

Негізгі бетке арналған маршрут келесідей болады

  1. urlpatterns = [
  2. url(r'^$', views.IndexView.as_view(), name='index')
  3. ]

рет көру.py

Енді мақалалар тізімін немесе бүкіл бетті бірден қайтаратын көріністі қарастырыңыз

  1. class IndexView(View):
  2. template_name = 'index.html'
  3.  
  4. def get(self, request):
  5. return render(request=request, template_name=self.template_name, context={'object_list': get_paginated_page(request, Article.objects.all())})
  6.  
  7. def post(self, request):
  8. if request.is_ajax():
  9. return JsonResponse({
  10. "result": True,
  11. "articles": render_to_string(
  12. request=request,
  13. template_name='article_previews_list.html',
  14. context={'object_list': get_paginated_page(request, Article.objects.all())}
  15. )
  16. })
  17. else:
  18. raise Http404()

Маңызды мәселе - сайт сұраулардың екі түрін де, әдеттегі және AJAX сұрауларын да дұрыс өңдеуі керек. Өйткені пайдаланушы тікелей беттердің біріне де, сайттағы беттеуді де пайдалана алады.

Сізді осы кодтағы get_paginated_page әдісі қызықтыруы мүмкін, ол Paginator класын пайдаланып көрсету үшін қажетті бетті жасайды.

  1. # -*- coding: utf-8 -*-
  2.  
  3. from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
  4.  
  5.  
  6. def get_paginated_page(request, objects, number=10):
  7. current_page = Paginator(objects, number)
  8. page = request.GET.get('page') if request.method == 'GET' else request.POST.get('page')
  9. try:
  10. return current_page.page(page)
  11. except PageNotAnInteger:
  12. return current_page.page(1)
  13. except EmptyPage:
  14. return current_page.page(current_page.num_pages)

Django үшін Timeweb хостының VDS-сервері ұсынамын.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

B
  • Ақп. 24, 2020, 11:37 Т.Ж.

Евгений Здравствуйте! Не могу понять вот эту часть кода: url: jQuery(this).attr('action')
наверное здесь должен быть путь к url, тогда 'action' на какой url указывает?

Evgenii Legotckoi
  • Ақп. 24, 2020, 2:54 Т.Қ.

Добрый день. Там будет url, на который указывает ссылка тега a в пагинаторе, если правильно помню )) Написал этот код и забыл.

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз