sql >> Databáze >  >> RDS >> Mysql

Vytvoření webové aplikace od nuly pomocí Python Flask a MySQL:Část 5

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">&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>

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('&laquo;')));

$('.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('&raquo;')));

$('.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('&laquo;'));

    $(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('&raquo;').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('&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);
        }
    });
}

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.


  1. Základy tabulkových výrazů, 2. část – Odvozené tabulky, logické úvahy

  2. Snadná obsluha CRUD s připojením k databázi PDO

  3. Postgresql generuje_řadu měsíců

  4. Příklady vztahů mnoho k mnoha