sql >> Database >  >> RDS >> Mysql

Een web-app maken vanaf nul met Python Flask en MySQL:deel 5

In het vorige deel van deze serie hebben we gezien hoe de Edit . te implementeren en Delete wensfunctionaliteit voor onze Bucket List-applicatie. In dit deel zullen we de paging-functionaliteit voor onze home-lijst van gebruikers implementeren.

Aan de slag

Laten we beginnen met het klonen van het vorige deel van de tutorial van GitHub.

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

Nadat de broncode is gekloond, navigeert u naar de projectdirectory en start u de webserver.

cd PythonFlaskMySQLApp_Part4
python app.py

Ga met je browser naar http://localhost:5002/ en je zou de app moeten laten draaien.

Paginering implementeren

Naarmate de lijst met wensen op de homepage van de gebruiker groter wordt, wordt deze naar beneden gescrold. Het is dus belangrijk om paginering te implementeren. We beperken het aantal items dat op een pagina wordt weergegeven tot een bepaald aantal.

Wijzig de procedure voor het verkrijgen van een wens

We beginnen met het aanpassen van de sp_GetWishByUser procedure om resultaten te retourneren op basis van een limit en offset waarde. Deze keer zullen we onze opgeslagen procedure-instructie dynamisch maken om de resultaatset te retourneren op basis van de limiet- en offsetwaarde. Hier is de gewijzigde sp_GetWishByUser MySQL opgeslagen procedure.

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 ;

Zoals te zien is in de bovenstaande opgeslagen procedure, hebben we onze dynamische SQL-query gemaakt en uitgevoerd om de verlanglijst te krijgen op basis van de offset en limit parameters.

Paginering toevoegen aan de gebruikersinterface

Laten we eerst een paar standaardinstellingen definiëren. In app.py voeg een variabele toe voor paginalimiet.

# Default setting
pageLimit = 2

Maak de getWish python-methode accepteert POST-verzoeken.

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

Lees de offset en limit binnen de getWish methode en geef deze door tijdens het aanroepen van de MySQL-opgeslagen procedure sp_GetWishByUser .

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


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


Wijzig de GetWishes JavaScript-functie in userHome.html om er een POST-verzoek van te maken en de offset . door te geven waarde.

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

Sla alle wijzigingen op en start de server opnieuw op. Meld u aan met een geldig e-mailadres en wachtwoord en er zouden slechts twee records op het scherm moeten worden weergegeven.

Het databasegedeelte werkt dus goed. Vervolgens moeten we de gebruikersinterface voor paginering toevoegen aan de startpagina van de gebruiker, zodat de gebruiker door de gegevens kan navigeren.

We gebruiken de Bootstrap-paginatiecomponent. Open userHome.html en voeg de volgende HTML-code toe na de #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>

Sla de wijzigingen op en start de server opnieuw op. Nadat u zich heeft aangemeld, zou u de paginering onder de verlanglijst moeten kunnen zien.

Paginering dynamisch maken

De bovenstaande paginering is hoe onze paginering eruit zal zien. Maar om het functioneel te maken, moeten we onze paginering dynamisch maken op basis van het aantal records in de database.

Om onze paginering te maken, hebben we het totale aantal records nodig dat beschikbaar is in de database. Dus laten we de MySQL-opgeslagen procedure aanpassen sp_GetWishByUser om het totale aantal beschikbare records als een out-parameter te retourneren.

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 ;

Zoals te zien is in de bovenstaande gewijzigde opgeslagen procedure, hebben we een nieuwe uitvoerparameter toegevoegd met de naam p_total en selecteerde het totale aantal wensen op basis van de gebruikers-ID.

Wijzig ook de getWish python-methode om een ​​uitvoerparameter door te geven.

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

Zoals je kunt zien in de bovenstaande code, sluiten we de cursor zodra we de opgeslagen procedure hebben aangeroepen en openen we een nieuwe cursor om de geretourneerde out-parameter te selecteren.

Eerder stuurden we een lijst met wensen van de Python-methode terug. Nu moeten we ook het totale aantal records opnemen in de geretourneerde JSON. Dus we zullen het verlanglijstje van de verlanglijst in een andere lijst maken en vervolgens de verlanglijst en het aantal records aan de hoofdlijst toevoegen. Hier is de gewijzigde code van de 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 de GetWishes JavaScript-functie, voeg binnen de succesvolle callback een consolelog toe.

console.log(res);

Sla alle bovenstaande wijzigingen op en start de server opnieuw op. Meld u aan met een geldig e-mailadres en wachtwoord en controleer op de startpagina van de gebruiker de browserconsole. U zou een antwoord moeten kunnen zien dat lijkt op het antwoord dat hieronder wordt weergegeven:

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

Met behulp van het totale aantal ontvangen van de reactie, kunnen we het totale aantal pagina's krijgen.

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

Het totale aantal items delen van itemsPerPage count geeft ons het aantal benodigde pagina's. Maar dit geldt alleen als het totaal een veelvoud is van itemsPerPage . Als dat niet het geval is, moeten we dat controleren en het aantal pagina's dienovereenkomstig aanpassen.

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

Dus dat geeft ons het juiste aantal pagina's.

Omdat we nu het totale aantal pagina's hebben, maken we de paginering-HTML dynamisch. Verwijder de LI element uit de paginering-HTML die we eerder hebben toegevoegd.

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

In de GetWishes succes terugbellen, laten we de vorige link dynamisch maken met jQuery.

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

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

In de bovenstaande code hebben we zojuist de vorige knoplink gemaakt en toegevoegd aan de paginering UL.

Sla de bovenstaande wijzigingen op en start de server opnieuw op. Na succesvolle aanmelding zou u de vorige link onder de lijst moeten kunnen zien.

Laten we op dezelfde manier de pagina's in de paginering toevoegen op basis van het aantal pagina's.

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

Laten we ook de link Volgende toevoegen nadat de link naar de pagina's is toegevoegd.

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

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

Sla de wijzigingen op en start de server opnieuw op. Meld u aan met een geldig e-mailadres en wachtwoord, en eenmaal op de startpagina van de gebruiker zou u de paginering moeten kunnen zien.

Een klikgebeurtenis aan een paginanummer koppelen

Nu komt de belangrijkste logica die onze paginering functioneel zal maken. Wat we gaan doen, is een klikgebeurtenisaanroep toevoegen aan elke pagina-index om de GetWishes aan te roepen JavaScript-functie. Laten we eerst een klikgebeurtenis koppelen aan het ankerelement dat het paginanummer weergeeft.

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

}

Dus we hebben zojuist een onclick-gebeurtenis toegevoegd aan het pagina-anker. Bij elke klik bellen we de GetWishes functie en geef de offset . door . Dus declareer de offset buiten de for-lus.

var offset = 0;

Bel de GetWishes functie binnen de klikgebeurtenisaanroep.

GetWishes(offset);

Verhoog ook de offset gebaseerd op het aantal getoonde records.

offset = offset + 2;

Maar elke keer dat de GetWishes functie wordt aangeroepen, de waarde van offset is altijd de laatste set. We zullen dus gebruik maken van JavaScript-sluitingen om de juiste offset door te geven aan de GetWishes functie.

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;

}

Sla alle bovenstaande wijzigingen op en start de server opnieuw op. Log in met geldige inloggegevens en klik op de startpagina van de gebruiker op de pagina's in de UL voor paginering.

Vervolgens implementeren we de links naar de vorige en volgende pagina. Het lijkt misschien een beetje ingewikkeld, dus laat me het een beetje uitleggen voordat we beginnen met de implementatie.

We geven vijf pagina's tegelijk weer. Met de volgende en vorige link kan de gebruiker respectievelijk naar de volgende vijf en de vorige vijf pagina's navigeren. We slaan de waarden van de startpagina en de eindpagina op en blijven zowel bij de volgende als de vorige klik op de knop bijwerken. Dus laten we beginnen met het toevoegen van twee verborgen velden aan de userHome.html pagina.

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

In de GetWishes succes terugbellen, nadat we de .pagination . hebben geleegd UL, voeg de volgende regel code toe om de laatste startpagina en eindpagina te krijgen.

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

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

Er wordt geen link naar de vorige knop weergegeven bij het weergeven van pagina's 1 tot 5. Als de weergegeven pagina's groter zijn dan 5, geven we de link naar de vorige knop weer.

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

Wanneer de gebruiker op de vorige knop klikt, resetten we de hdnStart en hdnEnd waarden en roep de GetWishes JavaScript-functie.

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

Vervolgens zullen we op basis van de startpagina en de eindpagina een lus maken en de paginalinks maken en de .pagination toevoegen 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);


}

Door het totale aantal pagina's en de startwaarde van de pagina te vergelijken, bepalen we de weergave van de volgende knoplink.

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

Zoals te zien is in de bovenstaande code, resetten we bij de volgende klik op de knop de hdnStart en hdnEnd knopwaarden en het aanroepen van de GetWishes JavaScript-functie.

Dus hier is de laatste GetWishes JavaScript-functie.

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

Sla alle bovenstaande wijzigingen op en start de server opnieuw op. Log in met een geldig e-mailadres en wachtwoord. U zou de volledig functionele paginering voor de gebruikersverlanglijst moeten kunnen zien.


  1. Hoe maak je een externe sleutel in Oracle SQL Developer?

  2. Hoe CHAR() werkt in MariaDB

  3. Fout bij het verbinden met postgresql met behulp van sqlalchemy

  4. Stopwoorden en Stoplist gebruiken om SQL Server Full-Text Search (FTS) te verbeteren