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

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

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

Мәселе мынада: пайдаланушы мақалалар тізімі бар келесі бетке өткісі келгенде және 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-сервері ұсынамын.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

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

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

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

Evgenii Legotckoi
  • Ақп. 24, 2020, 3:54 Т.Ж.

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

Пікірлер

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

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:66ұпай,
  • Бағалау ұпайлары-1
t

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:33ұпай,
  • Бағалау ұпайлары-10
t

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:52ұпай,
  • Бағалау ұпайлары-4
Соңғы пікірлер
G
GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrАқп. 8, 2024, 6:43 Т.Қ.
Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
FynjyШілде 22, 2024, 4:15 Т.Ж.
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCTМаусым 25, 2024, 1 Т.Ж.
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCTМамыр 5, 2024, 5:46 Т.Ж.
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

Бізді әлеуметтік желілерде бақылаңыз