Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Erstellen einer Web-App von Grund auf neu mit Python Flask und MySQL:Teil 5

Im vorherigen Teil dieser Serie haben wir gesehen, wie man Edit implementiert und Delete Wunschfunktionalität für unsere Bucket List Application. In diesem Teil implementieren wir die Paging-Funktionalität für unsere Benutzer-Home-Liste.

Erste Schritte

Beginnen wir damit, den vorherigen Teil der Anleitung von GitHub zu klonen.

git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part4.git

Navigieren Sie nach dem Klonen des Quellcodes zum Projektverzeichnis und starten Sie den Webserver.

cd PythonFlaskMySQLApp_Part4
python app.py

Richten Sie Ihren Browser auf http://localhost:5002/ und Sie sollten die Anwendung ausführen.

Paginierung implementieren

Wenn die Wunschliste auf der Startseite des Nutzers länger wird, wird sie auf der Seite nach unten gescrollt. Daher ist es wichtig, die Paginierung zu implementieren. Wir begrenzen die Anzahl der auf einer Seite angezeigten Elemente auf eine bestimmte Anzahl.

Modifizieren Sie das „Get Wish“-Verfahren

Wir beginnen mit der Änderung von sp_GetWishByUser Prozedur, um Ergebnisse basierend auf einem limit zurückzugeben und offset Wert. Dieses Mal erstellen wir unsere Stored Procedure-Anweisung dynamisch, um die Ergebnismenge basierend auf dem Grenzwert und dem Offsetwert zurückzugeben. Hier ist der modifizierte sp_GetWishByUser Gespeicherte MySQL-Prozedur.

USE `BucketList`;
DROP procedure IF EXISTS `sp_GetWishByUser`;

DELIMITER $$
USE `BucketList`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishByUser`(
IN p_user_id bigint,
IN p_limit int,
IN p_offset int
)
BEGIN
    SET @t1 = CONCAT( 'select * from tbl_wish where wish_user_id = ', p_user_id, ' order by wish_date desc limit ',p_limit,' offset ',p_offset);
	PREPARE stmt FROM @t1;
	EXECUTE stmt;
	DEALLOCATE PREPARE stmt1;
END$$

DELIMITER ;

Wie in der obigen gespeicherten Prozedur zu sehen ist, haben wir unsere dynamische SQL-Abfrage erstellt und ausgeführt, um die Wunschliste basierend auf dem offset zu erhalten und limit Parameter.

Paginierung zur Benutzeroberfläche hinzufügen

Lassen Sie uns zunächst einige Standardeinstellungen definieren. In app.py Fügen Sie eine Variable für das Seitenlimit hinzu.

# Default setting
pageLimit = 2

Machen Sie den getWish Python-Methode akzeptiert POST-Anfragen.

@app.route('/getWish',methods=['POST'])

Lesen Sie den offset und limit innerhalb von getWish -Methode und übergeben sie beim Aufrufen der gespeicherten MySQL-Prozedur sp_GetWishByUser .

 _limit = pageLimit
 _offset = request.form['offset']


con = mysql.connect()
cursor = con.cursor()
cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset))
wishes = cursor.fetchall()


Ändern Sie die GetWishes JavaScript-Funktion in userHome.html um es zu einer POST-Anfrage zu machen und den offset zu übergeben Wert.

function GetWishes() {
    $.ajax({
        url: '/getWish',
        type: 'POST',
        data: {
            offset: 0
        },
        success: function(res) {

            var wishObj = JSON.parse(res);
            $('#ulist').empty();
            $('#listTemplate').tmpl(wishObj).appendTo('#ulist');

        },
        error: function(error) {
            console.log(error);
        }
    });
}

Speichern Sie alle Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an und Sie sollten nur zwei Einträge auf dem Bildschirm sehen.

Der Datenbankteil funktioniert also gut. Als Nächstes müssen wir die Paginierungs-UI zur Benutzer-Homepage hinzufügen, die es dem Benutzer ermöglicht, durch die Daten zu navigieren.

Wir verwenden die Bootstrap-Paginierungskomponente. Öffnen Sie userHome.html und fügen Sie den folgenden HTML-Code nach #ulist hinzu UL.

<nav>
    <ul class="pagination">
        <li>
            <a href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        <li><a href="#">1</a>
        </li>
        <li><a href="#">2</a>
        </li>
        <li><a href="#">3</a>
        </li>
        <li><a href="#">4</a>
        </li>
        <li><a href="#">5</a>
        </li>
        <li>
            <a href="#" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
    </ul>
</nav>

Speichern Sie die Änderungen und starten Sie den Server neu. Nach erfolgreicher Anmeldung sollten Sie die Seitennummerierung unter der Wunschliste sehen können.

Paginierung dynamisch gestalten

Die obige Paginierung ist, wie unsere Paginierung aussehen wird. Aber um es funktionsfähig zu machen, müssen wir unsere Paginierung dynamisch basierend auf der Anzahl der Datensätze in der Datenbank erstellen.

Um unsere Paginierung zu erstellen, benötigen wir die Gesamtzahl der in der Datenbank verfügbaren Datensätze. Ändern wir also die gespeicherte MySQL-Prozedur sp_GetWishByUser um die Gesamtzahl der verfügbaren Datensätze als Ausgangsparameter zurückzugeben.

USE `BucketList`;
DROP procedure IF EXISTS `sp_GetWishByUser`;

DELIMITER $$
USE `BucketList`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishByUser`(
IN p_user_id bigint,
IN p_limit int,
IN p_offset int,
out p_total bigint
)
BEGIN
    
	select count(*) into p_total from tbl_wish where wish_user_id = p_user_id;

	SET @t1 = CONCAT( 'select * from tbl_wish where wish_user_id = ', p_user_id, ' order by wish_date desc limit ',p_limit,' offset ',p_offset);
	PREPARE stmt FROM @t1;
	EXECUTE stmt;
	DEALLOCATE PREPARE stmt;
END$$

DELIMITER ;

Wie in der oben geänderten gespeicherten Prozedur zu sehen ist, haben wir einen neuen Ausgabeparameter namens p_total hinzugefügt und wählte die Gesamtzahl der Wünsche basierend auf der Benutzer-ID aus.

Ändern Sie auch getWish Python-Methode, um einen Ausgabeparameter zu übergeben.

 _limit = pageLimit
 _offset = request.form['offset']
 _total_records = 0


con = mysql.connect()
cursor = con.cursor()
cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset,_total_records))
wishes = cursor.fetchall()

cursor.close()

cursor = con.cursor()
cursor.execute('SELECT @_sp_GetWishByUser_3');

outParam = cursor.fetchall()

Wie Sie im obigen Code sehen können, schließen wir den Cursor, nachdem wir die gespeicherte Prozedur aufgerufen haben, und öffnen einen neuen Cursor, um den zurückgegebenen Ausgangsparameter auszuwählen.

Zuvor haben wir eine Liste mit Wünschen von der Python-Methode zurückgegeben. Jetzt müssen wir auch die Gesamtanzahl der Datensätze in das zurückgegebene JSON aufnehmen. Also machen wir das Wunschlisten-Wörterbuch zu einer anderen Liste und fügen dann die Wunschliste und die Datensatzanzahl zur Hauptliste hinzu. Hier ist der modifizierte Code von getWish Python-Methode.

response = []
wishes_dict = []

for wish in wishes:
    wish_dict = {
        'Id': wish[0],
        'Title': wish[1],
        'Description': wish[2],
        'Date': wish[4]}
    wishes_dict.append(wish_dict)
    
response.append(wishes_dict)
response.append({'total':outParam[0][0]}) 

return json.dumps(response)

In den GetWishes JavaScript-Funktion, innerhalb des Erfolgsrückrufs fügen Sie ein Konsolenprotokoll hinzu.

console.log(res);

Speichern Sie alle oben genannten Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an, und überprüfen Sie auf der Benutzer-Homepage die Browserkonsole. Sie sollten eine Antwort sehen, die der folgenden ähnelt:

[
    [{
        "Date": "Sun, 15 Feb 2015 15:10:45 GMT",
        "Description": "wwe",
        "Id": 5,
        "Title": "wwe"
    }, {
        "Date": "Sat, 24 Jan 2015 00:13:50 GMT",
        "Description": "Travel to Spain",
        "Id": 4,
        "Title": "Spain"
    }], {
        "total": 5
    }
]

Anhand der aus der Antwort erhaltenen Gesamtzahl können wir die Gesamtzahl der Seiten ermitteln.

var total = wishObj[1]['total'];
var pageCount = total/itemsPerPage;

Teilen der Gesamtzahl der Artikel durch itemsPerPage count gibt uns die Anzahl der benötigten Seiten. Dies gilt jedoch nur, wenn die Gesamtzahl ein Vielfaches von itemsPerPage ist . Wenn dies nicht der Fall ist, müssen wir dies überprüfen und die Seitenzahl entsprechend behandeln.

var pageRem = total%itemsPerPage;
if(pageRem !=0 ){
	pageCount = Math.floor(pageCount)+1;
}

Damit erhalten wir die richtige Seitenzahl.

Da wir jetzt die Gesamtzahl der Seiten haben, erstellen wir den Paginierungs-HTML dynamisch. Entfernen Sie das LI -Element aus dem Paginierungs-HTML, das wir zuvor hinzugefügt haben.

<nav>
    <ul class="pagination">
        // li we'll create dynamically
    </ul>
</nav>

In den GetWishes Erfolgs-Callback, lassen Sie uns den vorherigen Link dynamisch mit jQuery erstellen.

var prevLink = $('<li/>').append($('<a/>').attr({
        'href': '#'
    }, {
        'aria-label': 'Previous'
    })
    .append($('<span/>').attr('aria-hidden', 'true').html('&laquo;')));

$('.pagination').append(prevLink);

Im obigen Code haben wir einfach den vorherigen Schaltflächenlink erstellt und an die Paginierung UL angehängt.

Speichern Sie die obigen Änderungen und starten Sie den Server neu. Nach erfolgreicher Anmeldung sollten Sie den vorherigen Link unter der Liste sehen können.

Lassen Sie uns auf ähnliche Weise die Seiten in der Paginierung basierend auf der Seitenzahl hinzufügen.

for (var i = 0; i < pageCount; i++) {
    var page = $('<li/>').append($('<a/>').attr('href', '#').text(i + 1));
    $('.pagination').append(page);
}

Lassen Sie uns auch den Weiter-Link hinzufügen, nachdem der Seiten-Link hinzugefügt wurde.

var nextLink = $('<li/>').append($('<a/>').attr({
        'href': '#'
    }, {
        'aria-label': 'Next'
    })
    .append($('<span/>').attr('aria-hidden', 'true').html('&raquo;')));

$('.pagination').append(nextLink);

Speichern Sie die Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an, und sobald Sie auf der Benutzer-Homepage sind, sollten Sie die Paginierung sehen können.

Anhängen eines Klickereignisses an eine Seitenzahl

Jetzt kommt die Hauptlogik, die unsere Paginierung funktionsfähig macht. Was wir tun werden, ist, einen Click-Event-Aufruf an jeden Seitenindex anzuhängen, um die GetWishes aufzurufen JavaScript-Funktion. Lassen Sie uns zuerst ein Klick-Ereignis an das Ankerelement anhängen, das die Seitenzahl anzeigt.

for (var i = 0; i < pageCount; i++) {

    var aPage = $('<a/>').attr('href', '#').text(i + 1);
  
    $(aPage).click(function() {
        
    });
  
    var page = $('<li/>').append(aPage);
    $('.pagination').append(page);

}

Also haben wir einfach ein onclick-Ereignis an den Seitenanker angehängt. Bei jedem Klick rufen wir die GetWishes auf Funktion und übergeben Sie den offset . Deklarieren Sie also den offset außerhalb der for-Schleife.

var offset = 0;

Rufen Sie GetWishes auf Funktion innerhalb des Click-Event-Aufrufs.

GetWishes(offset);

Erhöhen Sie auch den offset basierend auf der Anzahl der angezeigten Datensätze.

offset = offset + 2;

Aber jedes Mal die GetWishes Funktion aufgerufen wird, der Wert von offset wird immer der letzte Satz sein. Daher verwenden wir JavaScript Closures, um den korrekten Offset an GetWishes zu übergeben Funktion.

var offset = 0;

for (var i = 0; i < pageCount; i++) {

    var aPage = $('<a/>').attr('href', '#').text(i + 1);
  
    $(aPage).click(function(offset) {
        return function() {
            GetWishes(offset);
        }
    }(offset));
  
    var page = $('<li/>').append(aPage);
    $('.pagination').append(page);
    offset = offset + itemsPerPage;

}

Speichern Sie alle oben genannten Änderungen und starten Sie den Server neu. Melden Sie sich mit gültigen Anmeldedaten an und versuchen Sie auf der Startseite des Nutzers, auf die Seiten im Paginierungs-UL zu klicken.

Als Nächstes implementieren wir die Links zur vorherigen und nächsten Seite. Es mag etwas kompliziert erscheinen, also lassen Sie mich es ein wenig erklären, bevor wir mit der Implementierung beginnen.

Wir werden fünf Seiten gleichzeitig anzeigen. Unter Verwendung des nächsten und vorherigen Links kann der Benutzer zu den nächsten fünf bzw. vorherigen fünf Seiten navigieren. Wir speichern die Werte der Startseite und der Endseite und aktualisieren sie sowohl beim nächsten als auch beim vorherigen Klick auf die Schaltfläche. Beginnen wir also damit, zwei versteckte Felder zur userHome.html hinzuzufügen Seite.

<input type="hidden" id="hdnStart" value="1" />
<input type="hidden" id="hdnEnd" value="5"/>

In den GetWishes Erfolgsrückruf, nachdem wir die .pagination geleert haben UL, fügen Sie die folgende Codezeile hinzu, um die neueste Startseite und Endseite zu erhalten.

$('.pagination').empty();

var pageStart = $('#hdnStart').val();
var pageEnd = $('#hdnEnd').val();

Bei der Anzeige der Seiten 1 bis 5 wird kein vorheriger Schaltflächen-Link angezeigt. Wenn mehr als 5 Seiten angezeigt werden, zeigen wir den vorherigen Schaltflächen-Link an.

if (pageStart > 5) {
    var aPrev = $('<a/>').attr({
            'href': '#'
        }, {
            'aria-label': 'Previous'
        })
        .append($('<span/>').attr('aria-hidden', 'true').html('&laquo;'));

    $(aPrev).click(function() {
        // Previous button logic
    });

    var prevLink = $('<li/>').append(aPrev);
    $('.pagination').append(prevLink);
}

Wenn der Nutzer auf die vorherige Schaltfläche klickt, setzen wir hdnStart zurück und hdnEnd Werte und rufen Sie die GetWishes auf JavaScript-Funktion.

$(aPrev).click(function() {
    $('#hdnStart').val(Number(pageStart) - 5);
    $('#hdnEnd').val(Number(pageStart) - 5 + 4);
    GetWishes(Number(pageStart) - 5);
});

Als nächstes erstellen wir basierend auf der Startseite und der Endseite eine Schleife und erstellen die Seitenlinks und hängen die .pagination an UL.

for (var i = Number(pageStart); i <= Number(pageEnd); i++) {

    if (i > pageCount) {
        break;
    }


    var aPage = $('<a/>').attr('href', '#').text(i);
    
    // Attach the page click event
    $(aPage).click(function(i) {
        return function() {
            GetWishes(i);
        }
    }(i));
    
    var page = $('<li/>').append(aPage);

    // Attach the active page class
    if ((_page) == i) {
        $(page).attr('class', 'active');
    }

    $('.pagination').append(page);


}

Durch den Vergleich der Gesamtseitenanzahl und des Seitenanfangswerts entscheiden wir über die Anzeige des nächsten Schaltflächenlinks.

if ((Number(pageStart) + 5) <= pageCount) {
    var nextLink = $('<li/>').append($('<a/>').attr({
            'href': '#'
        }, {
            'aria-label': 'Next'
        })
        .append($('<span/>').attr('aria-hidden', 'true').html('&raquo;').click(function() {
            $('#hdnStart').val(Number(pageStart) + 5);
            $('#hdnEnd').val(Number(pageStart) + 5 + 4);
            GetWishes(Number(pageStart) + 5);

        })));
    $('.pagination').append(nextLink);
}

Wie im obigen Code zu sehen, setzen wir beim Klicken auf die nächste Schaltfläche den hdnStart zurück und hdnEnd Schaltflächenwerte und Aufrufen der GetWishes JavaScript-Funktion.

Hier also die letzten GetWishes JavaScript-Funktion.

function GetWishes(_page) {

    var _offset = (_page - 1) * 2;
  
    $.ajax({
        url: '/getWish',
        type: 'POST',
        data: {
            offset: _offset
        },
        success: function(res) {

            var itemsPerPage = 2;

            var wishObj = JSON.parse(res);

            $('#ulist').empty();
            $('#listTemplate').tmpl(wishObj[0]).appendTo('#ulist');

            var total = wishObj[1]['total'];
            var pageCount = total / itemsPerPage;
            var pageRem = total % itemsPerPage;
            if (pageRem != 0) {
                pageCount = Math.floor(pageCount) + 1;
            }


            $('.pagination').empty();

            var pageStart = $('#hdnStart').val();
            var pageEnd = $('#hdnEnd').val();




            if (pageStart > 5) {
                var aPrev = $('<a/>').attr({
                        'href': '#'
                    }, {
                        'aria-label': 'Previous'
                    })
                    .append($('<span/>').attr('aria-hidden', 'true').html('&laquo;'));

                $(aPrev).click(function() {
                    $('#hdnStart').val(Number(pageStart) - 5);
                    $('#hdnEnd').val(Number(pageStart) - 5 + 4);
                    GetWishes(Number(pageStart) - 5);
                });

                var prevLink = $('<li/>').append(aPrev);
                $('.pagination').append(prevLink);
            }



            for (var i = Number(pageStart); i <= Number(pageEnd); i++) {

                if (i > pageCount) {
                    break;
                }


                var aPage = $('<a/>').attr('href', '#').text(i);

                $(aPage).click(function(i) {
                    return function() {
                        GetWishes(i);
                    }
                }(i));
                var page = $('<li/>').append(aPage);

                if ((_page) == i) {
                    $(page).attr('class', 'active');
                }

                $('.pagination').append(page);


            }
            if ((Number(pageStart) + 5) <= pageCount) {
                var nextLink = $('<li/>').append($('<a/>').attr({
                        'href': '#'
                    }, {
                        'aria-label': 'Next'
                    })
                    .append($('<span/>').attr('aria-hidden', 'true').html('&raquo;').click(function() {
                        $('#hdnStart').val(Number(pageStart) + 5);
                        $('#hdnEnd').val(Number(pageStart) + 5 + 4);
                        GetWishes(Number(pageStart) + 5);

                    })));
                $('.pagination').append(nextLink);
            }




        },
        error: function(error) {
            console.log(error);
        }
    });
}

Speichern Sie alle oben genannten Änderungen und starten Sie den Server neu. Melden Sie sich mit einer gültigen E-Mail-Adresse und einem Passwort an. Sie sollten die voll funktionsfähige Paginierung für die Benutzerwunschliste sehen können.