Mysql
 sql >> Database >  >> RDS >> Mysql

Creazione di un'app Web da zero utilizzando Python Flask e MySQL:parte 5

Nella parte precedente di questa serie, abbiamo visto come implementare la Edit e Delete wish funzionalità per la nostra applicazione Bucket List. In questa parte implementeremo la funzionalità di paging per il nostro elenco di utenti home.

Per iniziare

Iniziamo clonando la parte precedente del tutorial da GitHub.

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

Una volta clonato il codice sorgente, vai alla directory del progetto e avvia il server web.

cd PythonFlaskMySQLApp_Part4
python app.py

Punta il browser su http://localhost:5002/ e dovresti avere l'applicazione in esecuzione.

Implementazione dell'impaginazione

Man mano che l'elenco dei desideri nella home page dell'utente aumenta, viene fatto scorrere verso il basso nella pagina. Quindi è importante implementare l'impaginazione. Limiteremo il numero di elementi mostrati in una pagina a un certo numero.

Modifica la procedura di acquisizione dei desideri

Inizieremo modificando sp_GetWishByUser procedura per restituire i risultati in base a un limit e offset valore. Questa volta creeremo la nostra istruzione di stored procedure in modo dinamico per restituire il set di risultati in base al limite e al valore di offset. Ecco il sp_GetWishByUser modificato Procedura memorizzata 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 ;

Come visto nella procedura memorizzata sopra, abbiamo creato la nostra query SQL dinamica e l'abbiamo eseguita per ottenere la lista dei desideri basata sull'offset e limit parametri.

Aggiunta dell'impaginazione all'interfaccia utente

Innanzitutto, definiamo alcune impostazioni predefinite. In app.py aggiungi una variabile per il limite di pagine.

# Default setting
pageLimit = 2

Crea getWish python accetta richieste POST.

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

Leggi il offset e limit all'interno di getWish metodo e passarlo durante la chiamata alla stored procedure 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()


Modifica il GetWishes Funzione JavaScript in userHome.html per farne una richiesta POST e passare l'offset valore.

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

Salva tutte le modifiche e riavvia il server. Accedi utilizzando un indirizzo email e una password validi e dovresti avere solo due record visualizzati sullo schermo.

Quindi la parte del database funziona bene. Successivamente, dobbiamo aggiungere l'interfaccia utente di impaginazione alla home page dell'utente, che consentirà all'utente di navigare tra i dati.

Useremo il componente di impaginazione Bootstrap. Apri userHome.html e aggiungi il seguente codice HTML dopo #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>

Salva le modifiche e riavvia il server. Dopo aver eseguito correttamente l'accesso, dovresti essere in grado di vedere l'impaginazione nella lista dei desideri.

Rendere dinamica l'impaginazione

L'impaginazione sopra è come apparirà la nostra impaginazione. Ma per renderlo funzionale, dobbiamo creare la nostra impaginazione dinamicamente in base al numero di record nel database.

Per creare la nostra impaginazione, avremo bisogno del numero totale di record disponibili nel database. Quindi modifichiamo la stored procedure MySQL sp_GetWishByUser per restituire il numero totale di record disponibili come parametro 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 ;

Come visto nella procedura memorizzata modificata sopra, abbiamo aggiunto un nuovo parametro di output chiamato p_total e selezionato il conteggio totale dei desideri in base all'ID utente.

Modifica anche il getWish python per passare un parametro di output.

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

Come puoi vedere nel codice sopra, una volta chiamata la stored procedure chiudiamo il cursore e apriamo un nuovo cursore per selezionare il parametro restituito.

In precedenza, stavamo restituendo un elenco di desideri dal metodo Python. Ora, dobbiamo anche includere il conteggio totale dei record nel JSON restituito. Quindi trasformeremo il dizionario della lista dei desideri in un altro elenco e quindi aggiungeremo la lista dei desideri e il conteggio dei record all'elenco principale. Ecco il codice modificato di getWish metodo 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)

In GetWishes Funzione JavaScript, all'interno della callback di successo aggiungi un log della console.

console.log(res);

Salva tutte le modifiche precedenti e riavvia il server. Accedi utilizzando un indirizzo e-mail e una password validi e quando sei nella home page dell'utente, controlla la console del browser. Dovresti essere in grado di visualizzare una risposta simile a quella mostrata di seguito:

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

Utilizzando il conteggio totale ricevuto dalla risposta, possiamo ottenere il numero totale di pagine.

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

Dividendo il conteggio totale degli articoli da itemsPerPage count ci dà il numero di pagine richieste. Ma questo vale solo quando il totale è un multiplo di itemsPerPage . In caso contrario, dovremo verificarlo e gestire il conteggio delle pagine di conseguenza.

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

Questo ci darà il numero di pagine corretto.

Ora, poiché abbiamo il numero totale di pagine, creeremo l'HTML di impaginazione in modo dinamico. Rimuovere il LI elemento dall'HTML di paginazione che abbiamo aggiunto in precedenza.

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

In GetWishes callback di successo, creiamo il collegamento precedente in modo dinamico usando jQuery.

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

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

Nel codice sopra, abbiamo appena creato il collegamento del pulsante precedente e l'abbiamo aggiunto all'impaginazione UL.

Salva le modifiche precedenti e riavvia il server. Dopo l'accesso, dovresti essere in grado di vedere il link precedente sotto l'elenco.

Allo stesso modo, aggiungiamo le pagine nell'impaginazione in base al conteggio delle pagine.

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

Aggiungiamo anche il collegamento Avanti dopo che il collegamento alle pagine è stato aggiunto.

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

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

Salva le modifiche e riavvia il server. Accedi utilizzando un indirizzo email e una password validi e una volta nella home page dell'utente dovresti essere in grado di vedere l'impaginazione.

Allegare un evento di clic a un numero di pagina

Ora arriva la logica principale che renderà funzionale la nostra impaginazione. Quello che faremo è allegare una chiamata all'evento clic su ogni indice di pagina per chiamare il GetWishes funzione JavaScript. Per prima cosa alleghiamo un evento click all'elemento anchor che mostra il numero di pagina.

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

}

Quindi abbiamo appena allegato un evento onclick all'ancora della pagina. Ad ogni clic chiameremo GetWishes funzione e passare l'offset . Quindi dichiara l'offset fuori dal ciclo for.

var offset = 0;

Chiama GetWishes funzione all'interno della chiamata all'evento click.

GetWishes(offset);

Incrementa anche l'offset in base al numero di record visualizzati.

offset = offset + 2;

Ma ogni volta il GetWishes viene chiamata la funzione, il valore di offset sarà sempre l'ultimo set. Quindi utilizzeremo le chiusure JavaScript per passare l'offset corretto a GetWishes funzione.

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;

}

Salva tutte le modifiche precedenti e riavvia il server. Accedi utilizzando credenziali valide e una volta nella home page dell'utente, prova a fare clic sulle pagine nell'UL di impaginazione.

Successivamente, implementeremo i collegamenti alla pagina precedente e successiva. Può sembrare un po' complicato, quindi lascia che lo spieghi un po' prima di iniziare con l'implementazione.

Visualizzeremo cinque pagine alla volta. Utilizzando il collegamento successivo e precedente l'utente può passare rispettivamente alle cinque pagine successive e alle cinque precedenti. Memorizziamo i valori della pagina iniziale e della pagina finale e continueremo ad aggiornare sia il clic del pulsante successivo che quello precedente. Quindi iniziamo aggiungendo due campi nascosti a userHome.html pagina.

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

In GetWishes callback di successo, dopo aver svuotato il .pagination UL, aggiungi la seguente riga di codice per ottenere la pagina iniziale e la pagina finale più recenti.

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

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

Non verrà mostrato alcun collegamento al pulsante precedente durante la visualizzazione delle pagine da 1 a 5. Se le pagine visualizzate sono maggiori di 5, verrà visualizzato il collegamento al pulsante precedente.

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

Quando l'utente fa clic sul pulsante precedente, reimposteremo hdnStart e hdnEnd valori e chiama il GetWishes funzione JavaScript.

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

Successivamente, in base alla pagina iniziale e alla pagina finale, eseguiremo il ciclo e creeremo i collegamenti alla pagina e aggiungeremo il .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);


}

Confrontando il conteggio totale delle pagine e il valore iniziale della pagina, decideremo la visualizzazione del collegamento del pulsante successivo.

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

Come visto nel codice sopra, al clic del pulsante successivo stiamo reimpostando hdnStart e hdnEnd valori dei pulsanti e chiamando il GetWishes funzione JavaScript.

Quindi ecco il GetWishes finale funzione 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);
        }
    });
}

Salva tutte le modifiche precedenti e riavvia il server. Accedi utilizzando un indirizzo email e una password validi. Dovresti essere in grado di vedere l'impaginazione completamente funzionale per la lista dei desideri dell'utente.