Evgenii Legotckoi
Evgenii Legotckoi8. Januar 2018 02:52

Django - Tutorial 031. URL ändern ohne die Seite neu zu laden mit teilweisem Laden des Inhalts

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 .

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

B
  • 24. Februar 2020 00:37

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

Evgenii Legotckoi
  • 24. Februar 2020 03:54

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

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 10:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken