sql >> データベース >  >> RDS >> Mysql

Python FlaskとMySQLを使用してゼロからWebアプリを作成する:パート5

    このシリーズの前のパートでは、Editを実装する方法を見ました およびDelete バケットリストアプリケーションの機能を希望します。このパートでは、ユーザーホームリストのページング機能を実装します。

    はじめに

    チュートリアルの前の部分をGitHubから複製することから始めましょう。

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

    ソースコードのクローンが作成されたら、プロジェクトディレクトリに移動して、Webサーバーを起動します。

    cd PythonFlaskMySQLApp_Part4
    python app.py

    ブラウザでhttp:// localhost:5002 /を指定すると、アプリケーションが実行されているはずです。

    ページネーションの実装

    ユーザーのホームページの希望のリストが増えると、ページを下にスクロールします。したがって、ページネーションを実装することが重要です。 1ページに表示されるアイテムの数を特定の数に制限します。

    GetWishプロシージャを変更する

    まず、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 パラメータ。

    UIにページ付けを追加する

    まず、いくつかのデフォルト設定を定義しましょう。 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を変更します userHome.htmlのJavaScript関数 それを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);
            }
        });
    }

    すべての変更を保存して、サーバーを再起動します。有効なメールアドレスとパスワードを使用してサインインすると、画面に表示されるレコードは2つだけになります。

    したがって、データベース部分はうまく機能しています。次に、ページネーションUIをユーザーのホームページに追加する必要があります。これにより、ユーザーはデータ間を移動できるようになります。

    Bootstrapページネーションコンポーネントを使用します。 userHome.htmlを開きます #ulistの後に次の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>

    変更を保存して、サーバーを再起動します。サインインに成功すると、ウィッシュリストの下にページネーションが表示されるはずです。

    ページネーションを動的にする

    上記のページ付けは、私たちのページ付けがどのように見えるかです。ただし、機能させるには、データベース内のレコード数に基づいて動的にページネーションを作成する必要があります。

    ページネーションを作成するには、データベースで使用可能なレコードの総数が必要です。それでは、MySQLストアドプロシージャsp_GetWishByUserを変更しましょう。 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 ;

    上記の変更されたストアドプロシージャに見られるように、p_totalという新しい出力パラメータを追加しました。 そして、ユーザーIDに基づいてウィッシュの総数を選択しました。

    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クロージャを使用して、正しいオフセットを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のページをクリックしてみてください。

    次に、前のページと次のページのリンクを実装します。少し複雑に思えるかもしれませんので、実装を始める前に少し説明しましょう。

    一度に5ページを表示します。次と前のリンクを使用して、ユーザーはそれぞれ次の5ページと前の5ページに移動できます。開始ページと終了ページの値を保存し、次と前のボタンクリックの両方で更新を続けます。それでは、2つの非表示フィールドを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. PL/pgSQL関数のオプションの引数

    2. Office365の最新機能を入手する方法

    3. シリアル化可能な分離レベル

    4. SQLServerはアンダースコアをエスケープします