Mysql
 sql >> база данни >  >> RDS >> Mysql

Създаване на уеб приложение от нулата с помощта на Python Flask и MySQL:Част 5

В предишната част на тази серия видяхме как да приложим Edit и Delete пожелайте функционалност за нашето приложение Bucket List. В тази част ще внедрим функционалността за пейджинг за нашия начален списък с потребители.

Първи стъпки

Нека започнем с клониране на предишната част на урока от GitHub.

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

След като изходният код е клониран, отидете до директорията на проекта и стартирайте уеб сървъра.

cd PythonFlaskMySQLApp_Part4
python app.py

Насочете браузъра си към http://localhost:5002/ и трябва да стартирате приложението.

Внедряване на пагинация

Тъй като списъкът с желания на началната страница на потребителя се нараства, той се превърта надолу по страницата. Затова е важно да приложите пагинация. Ще ограничим броя на елементите, показани на страница до определен брой.

Променете процедурата за получаване на желание

Ще започнем с промяна на sp_GetWishByUser процедура за връщане на резултати въз основа на limit и offset стойност. Този път ще създадем динамично нашия оператор за съхранена процедура, за да върнем резултатния набор въз основа на стойността на ограничението и отместването. Ето модифицирания sp_GetWishByUser 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 ;

Както се вижда в горната съхранена процедура, създадохме нашата динамична SQL заявка и я изпълнихме, за да получим списъка с желания въз основа на offset и limit параметри.

Добавяне на страници към потребителския интерфейс

Първо, нека дефинираме няколко настройки по подразбиране. В app.py добавете променлива за ограничение на страниците.

# Default setting
pageLimit = 2

Направете getWish метод на python приема POST заявки.

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

Прочетете offset и limit вътре в getWish метод и го предайте, докато извиквате съхранената процедура на 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()


Променете GetWishes JavaScript функция в userHome.html за да го направите POST заявка и да предадете offset стойност.

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

Запазете всички промени и рестартирайте сървъра. Влезте с валиден имейл адрес и парола и трябва да имате само два записа, показани на екрана.

Така че частта от базата данни работи добре. След това трябва да добавим потребителския интерфейс за пагинация към началната страница на потребителя, което ще позволи на потребителя да се движи в данните.

Ще използваме компонента за пагинация на Bootstrap. Отворете userHome.html и добавете следния HTML код след #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>

Запазете промените и рестартирайте сървъра. След успешното влизане, трябва да можете да видите пагинацията под списъка с желания.

Направяне на пагинация динамична

Горната пагинация е как ще изглежда нашата пагинация. Но за да го направим функционален, трябва да създадем динамично нашата пагинация въз основа на броя на записите в базата данни.

За да създадем нашата пагинация, ще ни трябва общият брой записи, налични в базата данни. Така че нека променим съхранената процедура на MySQL sp_GetWishByUser за да върне общия брой записи, налични като изходящ параметър.

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 ;

Както се вижда в горната модифицирана съхранена процедура, добавихме нов изходен параметър, наречен p_total и избра общия брой на желанията въз основа на потребителския идентификатор.

Променете също getWish python метод за предаване на изходен параметър.

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

Както можете да видите в горния код, след като извикаме съхранената процедура, затваряме курсора и отваряме нов курсор, за да изберем върнатия параметър.

По-рано връщахме списък с желания от метода Python. Сега също трябва да включим общия брой записи в върнатия JSON. Така че ще направим речника на списъка с желания в друг списък и след това ще добавим списъка с желания и броя на записите към основния списък. Ето модифицирания код на getWish метод на 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)

В GetWishes JavaScript функция, вътре в успешното обратно извикване добавете конзолен журнал.

console.log(res);

Запазете всички горни промени и рестартирайте сървъра. Влезте с валиден имейл адрес и парола и когато сте на началната страница на потребителя, проверете конзолата на браузъра. Трябва да можете да видите отговор, подобен на показания по-долу:

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

Използвайки общия брой, получен от отговора, можем да получим общия брой страници.

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

Разделяне на общия брой елементи от itemsPerPage count ни дава необходимия брой страници. Но това важи само когато общата сума е кратна на itemsPerPage . Ако това не е така, ще трябва да проверим за това и съответно да обработваме броя на страниците.

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

Така че това ще ни даде правилния брой страници.

Сега, тъй като разполагаме с общия брой страници, ще създадем динамично HTML за пагинация. Премахнете LI елемент от HTML за пагинация, който добавихме по-рано.

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

В GetWishes успешно обратно извикване, нека създадем предишната връзка динамично с помощта на jQuery.

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

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

В кода по-горе току-що създадохме предишната връзка с бутон и я добавихме към UL пагинация.

Запазете горните промени и рестартирайте сървъра. При успешно влизане трябва да можете да видите предишната връзка под списъка.

По същия начин, нека добавим страниците в пагинацията въз основа на броя на страниците.

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

Нека добавим и връзката Следваща, след като връзката към страниците бъде добавена.

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

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

Запазете промените и рестартирайте сървъра. Влезте с валиден имейл адрес и парола и веднъж на началната страница на потребителя трябва да можете да видите пагинацията.

Прикачване на събитие за щракване към номер на страница

Сега идва основната логика, която ще направи пагинацията ни функционална. Това, което ще направим, е да прикачим извикване на събитие за кликване към всеки индекс на страница, за да извикаме GetWishes JavaScript функция. Нека първо прикачим събитие за щракване към елемента за закотвяне, показващ номера на страницата.

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

}

Така че току-що прикачихме събитие onclick към котвата на страницата. При всяко щракване ще извикаме GetWishes функция и предайте offset . Така че декларирайте offset извън цикъла for.

var offset = 0;

Обадете се на GetWishes функция в извикването на събитие за щракване.

GetWishes(offset);

Също така увеличете offset въз основа на броя на показаните записи.

offset = offset + 2;

Но всеки път GetWishes функцията се извиква, стойността на offset винаги ще бъде последният набор. Така че ще използваме JavaScript Closures, за да предадем правилното изместване към GetWishes функция.

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;

}

Запазете всички горни промени и рестартирайте сървъра. Влезте с валидни идентификационни данни и веднъж на началната страница на потребителя, опитайте да щракнете върху страниците в UL за пагинация.

След това ще приложим връзките към предишната и следващата страница. Може да изглежда малко сложно, така че позволете ми да го обясня малко, преди да започнем с внедряването.

Ще показваме пет страници наведнъж. Използвайки следващата и предишната връзка, потребителят може да навигира съответно до следващите пет и предходните пет страници. Ще съхраняваме стойностите на началната и крайната страница и ще продължим да актуализираме както при следващото, така и при предишното щракване върху бутон. Така че нека започнем с добавяне на две скрити полета към userHome.html страница.

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

В GetWishes успешно обратно извикване, след като сме изпразнили .pagination UL, добавете следния ред код, за да получите най-новата начална и крайна страница.

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

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

Няма да се показва връзка към предишния бутон, когато се показват страници от 1 до 5. Ако показаните страници са по-големи от 5, тогава ще покажем връзката към предишния бутон.

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

Когато потребителят щракне върху предишния бутон, ще нулираме hdnStart и hdnEnd стойности и извикайте GetWishes JavaScript функция.

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

След това, въз основа на началната и крайната страница, ще завъртим и ще създадем връзките към страницата и ще добавим .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);


}

Сравнявайки общия брой страници и началната стойност на страницата, ще решим как да се покаже връзката към следващия бутон.

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

Както се вижда в горния код, при следващото щракване върху бутон ние нулираме hdnStart и hdnEnd стойности на бутоните и извикване на GetWishes JavaScript функция.

И така, ето последният GetWishes 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);
        }
    });
}

Запазете всички горни промени и рестартирайте сървъра. Влезте с валиден имейл адрес и парола. Трябва да можете да видите напълно функционалната пагинация за потребителския списък с желания.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL НЕ В заявката

  2. Добавяне на множество колони СЛЕД определена колона в MySQL

  3. Как мога временно да деактивирам ограничение за външен ключ в MySQL?

  4. mysql_fetch_assoc():предоставеният аргумент не е валиден ресурс за MySQL резултат в php

  5. разделен със запетая низ от избрани стойности в mysql