V předchozí části této série jsme viděli, jak implementovat Edit
a Delete
funkce přání pro naši aplikaci Bucket List. V této části implementujeme funkci stránkování pro náš domovský seznam uživatelů.
Začínáme
Začněme klonováním předchozí části výukového programu z GitHubu.
git clone https://github.com/jay3dec/PythonFlaskMySQLApp_Part4.git
Po naklonování zdrojového kódu přejděte do adresáře projektu a spusťte webový server.
cd PythonFlaskMySQLApp_Part4 python app.py
Nasměrujte svůj prohlížeč na http://localhost:5002/ a aplikace by měla být spuštěna.
Implementace stránkování
Jak se seznam přání na domovské stránce uživatele zvětšuje, posouvá se na stránce dolů. Je tedy důležité implementovat stránkování. Počet položek zobrazených na stránce omezíme na určitý počet.
Upravte postup získání přání
Začneme úpravou sp_GetWishByUser
procedura pro vrácení výsledků na základě limit
a offset
hodnota. Tentokrát budeme dynamicky vytvářet náš příkaz uložené procedury, abychom vrátili sadu výsledků na základě limitu a hodnoty offsetu. Zde je upravený sp_GetWishByUser
Uložená procedura MySQL.
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 ;
Jak je vidět ve výše uvedené uložené proceduře, vytvořili jsme náš dynamický SQL dotaz a provedli jsme jej, abychom získali seznam přání na základě offset
a limit
parametry.
Přidání stránkování do uživatelského rozhraní
Nejprve definujeme několik výchozích nastavení. V app.py
přidejte proměnnou pro limit stránek.
# Default setting pageLimit = 2
Vytvořte getWish
metoda python přijímá požadavky POST.
@app.route('/getWish',methods=['POST'])
Přečtěte si offset
a limit
uvnitř getWish
metodu a předat ji při volání uložené procedury MySQL sp_GetWishByUser
.
_limit = pageLimit _offset = request.form['offset'] con = mysql.connect() cursor = con.cursor() cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset)) wishes = cursor.fetchall()
Upravte GetWishes
Funkce JavaScript v userHome.html
aby to byl požadavek POST a předal offset
hodnotu.
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); } }); }
Uložte všechny změny a restartujte server. Přihlaste se pomocí platné e-mailové adresy a hesla a na obrazovce by se měly zobrazit pouze dva záznamy.
Databázová část tedy funguje dobře. Dále musíme na domovskou stránku uživatele přidat stránkovací uživatelské rozhraní, které uživateli umožní procházet data.
Použijeme stránkovací komponentu Bootstrap. Otevřete userHome.html
a za #ulist
přidejte následující kód HTML UL.
<nav> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</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">»</span> </a> </li> </ul> </nav>
Uložte změny a restartujte server. Po úspěšném přihlášení byste měli být schopni vidět stránkování pod seznamem přání.
Dynamizace stránkování
Výše uvedené stránkování je to, jak bude naše stránkování vypadat. Aby to ale fungovalo, musíme stránkování vytvářet dynamicky na základě počtu záznamů v databázi.
K vytvoření naší stránkování budeme potřebovat celkový počet záznamů dostupných v databázi. Pojďme tedy upravit uloženou proceduru MySQL sp_GetWishByUser
vrátit celkový počet záznamů dostupných jako parametr out.
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 ;
Jak je vidět ve výše uvedené upravené uložené proceduře, přidali jsme nový výstupní parametr nazvaný p_total
a vybral celkový počet přání na základě ID uživatele.
Upravte také getWish
python pro předání výstupního parametru.
_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()
Jak můžete vidět ve výše uvedeném kódu, jakmile zavoláme uloženou proceduru, zavřeme kurzor a otevřeme nový kurzor pro výběr vráceného out parametru.
Dříve jsme vraceli seznam přání z metody Python. Nyní musíme do vráceného JSON zahrnout také celkový počet záznamů. Takže uděláme ze slovníku seznamu přání jiný seznam a poté přidáme seznam přání a počet záznamů do hlavního seznamu. Zde je upravený kód getWish
metoda python.
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)
V GetWishes
JavaScript funkce, uvnitř úspěšného zpětného volání přidat protokol konzoly.
console.log(res);
Uložte všechny výše uvedené změny a restartujte server. Přihlaste se pomocí platné e-mailové adresy a hesla a na domovské stránce uživatele zkontrolujte konzolu prohlížeče. Měli byste vidět odpověď podobnou té, která je zobrazena níže:
[ [{ "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 } ]
Pomocí celkového počtu obdrženého z odpovědi můžeme získat celkový počet stránek.
var total = wishObj[1]['total']; var pageCount = total/itemsPerPage;
Vydělení celkového počtu položek od itemsPerPage
count nám udává počet požadovaných stránek. To však platí pouze tehdy, je-li součet násobkem itemsPerPage
. Pokud tomu tak není, budeme to muset zkontrolovat a podle toho zacházet s počtem stránek.
var pageRem = total%itemsPerPage; if(pageRem !=0 ){ pageCount = Math.floor(pageCount)+1; }
To nám poskytne správný počet stránek.
Nyní, protože máme celkový počet stránek, vytvoříme stránkovací kód HTML dynamicky. Odstraňte LI
prvek ze stránkovacího HTML, který jsme přidali dříve.
<nav> <ul class="pagination"> // li we'll create dynamically </ul> </nav>
V GetWishes
úspěšné zpětné volání, pojďme vytvořit předchozí odkaz dynamicky pomocí jQuery.
var prevLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Previous' }) .append($('<span/>').attr('aria-hidden', 'true').html('«'))); $('.pagination').append(prevLink);
Ve výše uvedeném kódu jsme právě vytvořili předchozí odkaz na tlačítko a připojili jej k UL stránkování.
Uložte výše uvedené změny a restartujte server. Po úspěšném přihlášení byste měli vidět předchozí odkaz pod seznamem.
Podobně přidejte stránky do stránkování na základě počtu stránek.
for (var i = 0; i < pageCount; i++) { var page = $('<li/>').append($('<a/>').attr('href', '#').text(i + 1)); $('.pagination').append(page); }
Po přidání odkazu na stránky také přidejte odkaz Další.
var nextLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Next' }) .append($('<span/>').attr('aria-hidden', 'true').html('»'))); $('.pagination').append(nextLink);
Uložte změny a restartujte server. Přihlaste se pomocí platné e-mailové adresy a hesla, a jakmile se dostanete na domovskou stránku uživatele, měli byste vidět stránkování.
Připojení události kliknutí k číslu stránky
Nyní přichází hlavní logika, díky které bude naše stránkování funkční. Co uděláme, je připojit volání události kliknutí na každý index stránky, abychom zavolali GetWishes
Funkce JavaScript. Nejprve připojte událost kliknutí k prvku kotvy zobrazujícímu číslo stránky.
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); }
Takže jsme právě připojili událost onclick k kotvě stránky. Při každém kliknutí zavoláme GetWishes
a předejte offset
. Takže deklarujte offset
mimo smyčku for.
var offset = 0;
Zavolejte GetWishes
funkce uvnitř volání události kliknutí.
GetWishes(offset);
Zvyšte také offset
na základě počtu zobrazených záznamů.
offset = offset + 2;
Ale pokaždé, když GetWishes
je volána funkce, hodnota offset
bude vždy poslední sada. K předání správného offsetu do GetWishes
tedy použijeme uzávěry JavaScriptu funkce.
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; }
Uložte všechny výše uvedené změny a restartujte server. Přihlaste se pomocí platných přihlašovacích údajů a na domovské stránce uživatele zkuste kliknout na stránky v UL stránkování.
Dále implementujeme odkazy na předchozí a další stránku. Může se to zdát trochu komplikované, dovolte mi to proto trochu vysvětlit, než začneme s implementací.
Budeme zobrazovat pět stránek najednou. Pomocí následujícího a předchozího odkazu může uživatel přejít na dalších pět, respektive pět předchozích stránek. Uložíme hodnoty úvodní a koncové stránky a budeme je průběžně aktualizovat při dalším i předchozím kliknutí na tlačítko. Začněme tedy přidáním dvou skrytých polí do userHome.html
stránku.
<input type="hidden" id="hdnStart" value="1" /> <input type="hidden" id="hdnEnd" value="5"/>
V GetWishes
úspěšné zpětné volání poté, co jsme vyprázdnili .pagination
UL, přidejte následující řádek kódu, abyste získali nejnovější úvodní a koncovou stránku.
$('.pagination').empty(); var pageStart = $('#hdnStart').val(); var pageEnd = $('#hdnEnd').val();
Při zobrazení stránek 1 až 5 se nezobrazí žádný odkaz na předchozí tlačítko. Pokud jsou zobrazené stránky větší než 5, zobrazíme odkaz na předchozí tlačítko.
if (pageStart > 5) { var aPrev = $('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Previous' }) .append($('<span/>').attr('aria-hidden', 'true').html('«')); $(aPrev).click(function() { // Previous button logic }); var prevLink = $('<li/>').append(aPrev); $('.pagination').append(prevLink); }
Když uživatel klikne na předchozí tlačítko, resetujeme hdnStart
a hdnEnd
hodnoty a zavolejte GetWishes
Funkce JavaScript.
$(aPrev).click(function() { $('#hdnStart').val(Number(pageStart) - 5); $('#hdnEnd').val(Number(pageStart) - 5 + 4); GetWishes(Number(pageStart) - 5); });
Dále na základě úvodní stránky a koncové stránky vytvoříme smyčku a vytvoříme odkazy na stránky a připojíme .pagination
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); }
Porovnáním celkového počtu stránek a počáteční hodnoty stránky rozhodneme o zobrazení odkazu na další tlačítko.
if ((Number(pageStart) + 5) <= pageCount) { var nextLink = $('<li/>').append($('<a/>').attr({ 'href': '#' }, { 'aria-label': 'Next' }) .append($('<span/>').attr('aria-hidden', 'true').html('»').click(function() { $('#hdnStart').val(Number(pageStart) + 5); $('#hdnEnd').val(Number(pageStart) + 5 + 4); GetWishes(Number(pageStart) + 5); }))); $('.pagination').append(nextLink); }
Jak je vidět ve výše uvedeném kódu, při dalším kliknutí na tlačítko resetujeme hdnStart
a hdnEnd
hodnoty tlačítka a volání GetWishes
Funkce JavaScript.
Takže tady je poslední GetWishes
Funkce JavaScript.
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('«')); $(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('»').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); } }); }
Uložte všechny výše uvedené změny a restartujte server. Přihlaste se pomocí platné e-mailové adresy a hesla. Měli byste vidět plně funkční stránkování seznamu přání uživatele.