sql >> Databasteknik >  >> RDS >> Mysql

Skapa en webbapp från grunden med Python Flask och MySQL:Del 5

I föregående del av den här serien såg vi hur man implementerar Edit och Delete önskar funktionalitet för vår Bucket List-applikation. I den här delen kommer vi att implementera personsökningsfunktionen för vår användarhemlista.

Komma igång

Låt oss börja med att klona den föregående delen av handledningen från GitHub.

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

När källkoden har klonats, navigera till projektkatalogen och starta webbservern.

cd PythonFlaskMySQLApp_Part4
python app.py

Peka med din webbläsare till http://localhost:5002/ och du bör ha appen igång.

Implementera paginering

När listan med önskemål på användarens hemsida ökar, rullas den nedåt på sidan. Så det är viktigt att implementera paginering. Vi kommer att begränsa antalet objekt som visas på en sida till ett visst antal.

Ändra Get Wish-proceduren

Vi börjar med att ändra sp_GetWishByUser procedur för att returnera resultat baserat på en limit och offset värde. Den här gången kommer vi att skapa vår lagrade procedursats dynamiskt för att returnera resultatuppsättningen baserat på gräns- och offsetvärdet. Här är den modifierade sp_GetWishByUser MySQL lagrad procedur.

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 ;

Som framgår av den lagrade proceduren ovan skapade vi vår dynamiska SQL-fråga och körde den för att få önskelistan baserad på offset och limit parametrar.

Lägga till paginering i användargränssnittet

Låt oss först definiera några standardinställningar. I app.py lägg till en variabel för sidgräns.

# Default setting
pageLimit = 2

Gör getWish python-metoden accepterar POST-förfrågningar.

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

Läs offset och limit inuti getWish metod och skicka den vidare medan du anropar den lagrade MySQL-proceduren sp_GetWishByUser .

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


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


Ändra GetWishes JavaScript-funktion i userHome.html för att göra det till en POST-begäran och skicka offset värde.

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);
        }
    });
}

Spara alla ändringar och starta om servern. Logga in med en giltig e-postadress och lösenord och du bör bara ha två poster som visas på skärmen.

Så databasdelen fungerar bra. Därefter måste vi lägga till pagineringsgränssnittet på användarens hemsida, vilket gör det möjligt för användaren att navigera över data.

Vi kommer att använda Bootstrap pagineringskomponenten. Öppna userHome.html och lägg till följande HTML-kod efter #ulist 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>

Spara ändringarna och starta om servern. Efter att ha lyckats logga in bör du kunna se sidnumren under önskelistan.

Gör paginering dynamisk

Ovanstående paginering är hur vår paginering kommer att se ut. Men för att göra det funktionellt måste vi skapa vår paginering dynamiskt baserat på antalet poster i databasen.

För att skapa vår paginering behöver vi det totala antalet poster som är tillgängliga i databasen. Så låt oss ändra MySQL-lagrade proceduren sp_GetWishByUser för att returnera det totala antalet tillgängliga poster som en ut-parameter.

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 ;

Som framgår av ovanstående modifierade lagrade procedur lade vi till en ny utdataparameter som heter p_total och valde det totala antalet önskemål baserat på användar-ID.

Ändra även getWish python-metod för att skicka en utdataparameter.

 _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()

Som du kan se i koden ovan, när vi väl har anropat den lagrade proceduren stänger vi markören och öppnar en ny markör för att välja den returnerade parametern.

Tidigare returnerade vi en lista med önskemål från Python-metoden. Nu måste vi också inkludera det totala antalet poster i den returnerade JSON. Så vi gör om önskelistan till en annan lista och lägger sedan till önskelistan och antalet rekord till huvudlistan. Här är den modifierade koden för getWish python-metoden.

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)

I GetWishes JavaScript-funktion, inuti framgångsåteruppringningen lägg till en konsollogg.

console.log(res);

Spara alla ovanstående ändringar och starta om servern. Logga in med en giltig e-postadress och lösenord och när du är på användarens hemsida, kontrollera webbläsarkonsolen. Du bör kunna se ett svar som liknar det som visas nedan:

[
    [{
        "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
    }
]

Med hjälp av det totala antalet mottaget från svaret kan vi få det totala antal sidor.

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

Dela det totala antalet varor från itemsPerPage count ger oss antalet sidor som krävs. Men detta gäller bara när summan är en multipel av itemsPerPage . Om så inte är fallet måste vi kontrollera det och hantera sidräkningen därefter.

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

Så det ger oss rätt sidantal.

Nu eftersom vi har det totala antalet sidor, skapar vi siderings-HTML dynamiskt. Ta bort LI element från siderings-HTML som vi lade till tidigare.

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

I GetWishes framgångsrik återuppringning, låt oss skapa den föregående länken dynamiskt med jQuery.

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

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

I ovanstående kod skapade vi bara den föregående knapplänken och lade till den till sidnumren UL.

Spara ändringarna ovan och starta om servern. Vid lyckad inloggning bör du kunna se föregående länk under listan.

På samma sätt, låt oss lägga till sidorna i sidnumreringen baserat på antalet sidor.

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

Låt oss också lägga till nästa länk efter att sidlänken har lagts till.

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

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

Spara ändringarna och starta om servern. Logga in med en giltig e-postadress och lösenord, och en gång på användarens hemsida bör du kunna se sidnumren.

Bifoga en klickhändelse till ett sidnummer

Nu kommer huvudlogiken som kommer att göra vår paginering funktionell. Vad vi ska göra är att bifoga ett klickhändelseanrop på varje sidindex för att anropa GetWishes JavaScript-funktion. Låt oss först bifoga en klickhändelse till ankarelementet som visar sidnumret.

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);

}

Så vi bifogade bara en onclick-händelse till sidankaret. Vid varje klick anropar vi GetWishes funktion och skicka offset . Så deklarera offset utanför for-slingan.

var offset = 0;

Ring GetWishes funktion i klickhändelseanropet.

GetWishes(offset);

Öka även offset baserat på antalet visade poster.

offset = offset + 2;

Men varje gång GetWishes funktionen anropas, värdet på offset kommer alltid att vara den sista uppsättningen. Så vi kommer att använda JavaScript-stängningar för att skicka rätt offset till GetWishes 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;

}

Spara alla ovanstående ändringar och starta om servern. Logga in med giltiga referenser och en gång på användarens hemsida, försök att klicka på sidorna i sidnumreringen UL.

Därefter implementerar vi länkarna till föregående och nästa sida. Det kan verka lite komplicerat, så låt mig förklara det lite innan vi börjar med implementeringen.

Vi kommer att visa fem sidor åt gången. Genom att använda nästa och föregående länk kan användaren navigera till nästa fem respektive föregående fem sidor. Vi lagrar värdena för startsidan och slutsidan och fortsätter att uppdatera både vid nästa och föregående knappklick. Så låt oss börja med att lägga till två dolda fält till userHome.html sida.

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

I GetWishes framgångsrik återuppringning efter att vi har tömt .pagination UL, lägg till följande kodrad för att få den senaste startsidan och slutsidan.

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

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

Ingen tidigare knapplänk kommer att visas när sidorna 1 till 5 visas. Om sidorna som visas är fler än 5 kommer vi att visa föregående knapplänk.

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);
}

När användaren klickar på föregående knapp återställer vi hdnStart och hdnEnd värden och anropa GetWishes JavaScript-funktion.

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

Därefter, baserat på startsidan och slutsidan, går vi en loop och skapar sidlänkarna och lägger till .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);


}

Genom att jämföra det totala sidantalet och sidans startvärde bestämmer vi visningen av nästa knapplänk.

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);
}

Som framgår av koden ovan, vid nästa knappklick återställer vi hdnStart och hdnEnd knappvärden och anropa GetWishes JavaScript-funktion.

Så här är den sista 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);
        }
    });
}

Spara alla ovanstående ändringar och starta om servern. Logga in med en giltig e-postadress och lösenord. Du bör kunna se den fullt fungerande sidnumren för användarens önskelista.


  1. 4 sätt att lista vyerna i en SQLite-databas

  2. Är det möjligt att välja sql-serverdata med kolumnordningsposition

  3. ORA-00001 unik begränsning överträtt

  4. cursor.execute(INSERT INTO im_entry.test (+entrym+) VALUES ('+p+');)