Advertisement
  1. Code
  2. Python

Membuat Aplikasi Web dari Awal dengan Python Flask dan MySQL: Bagian 5

Scroll to top
Read Time: 12 min
This post is part of a series called Creating a Web App From Scratch Using Python Flask and MySQL.
Creating a Web App From Scratch Using Python Flask and MySQL: Part 4
Creating a Web App From Scratch Using Python Flask and MySQL: Part 6

Indonesian (Bahasa Indonesia) translation by Aditia Dwiperdana (you can also view the original English article)

Pada bagian sebelumnya dari seri ini, kita lihat bagaimana mengimplementasi fungsi Edit dan Delete keinginan untuk Aplikasi Daftar Keinginan kita. Pada bagian ini kita akan mengimplementasi fitur pembagian halaman untuk daftar pada halaman beranda user.

Memulai

Kita mulai dengan membuat klon dari tutorial sebelumnya dari GitHub.

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

Setelah source code di-klon, masuk ke direktori proyek dan jalankan web server.

1
cd PythonFlaskMySQLApp_Part4
2
python app.py

Arahkan browser ke http://localhost:5002/ dan aplikasi akan berjalan.

Mengimplementasi Pagination

Saat daftar keinginan pada halaman beranda user berkembang, daftar keinginan akan bergulir ke bawah halaman. Jadi penting untuk mengimplementasi pagination. Kita akan membatasi jumlah butir yang ditampilkan di halaman.

Modifikasi Prosedur Get Wish

Kita mulai dengan memodifikasi prosedur sp_GetWishByUser untuk mengembalikan nilai berdasarkan nilai limit dan offset. Kali ini kita akan membuat pernyataan stored procedure secara dinamis untuk mengembalikan set berdasarkan nilai limit dan offset. Berikut adalah stored procedure MySQL sp_GetWishByUser yang sudah dimodifikasi.

1
USE `BucketList`;
2
DROP procedure IF EXISTS `sp_GetWishByUser`;
3
4
DELIMITER $$
5
USE `BucketList`$$
6
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishByUser`(
7
IN p_user_id bigint,
8
IN p_limit int,
9
IN p_offset int
10
)
11
BEGIN
12
    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);
13
  PREPARE stmt FROM @t1;
14
	EXECUTE stmt;
15
	DEALLOCATE PREPARE stmt1;
16
END$$
17
18
DELIMITER ;
19

Seperti yang bisa dilihat di stored procedure di atas, kita membuat query SQL dinamis dan menjalankannya untuk mendapat daftar keinginan berdasarkan parameter offset dan limit.

Menambahkan Pagination pada Antarmuka

Pertama, kita definisikan beberapa pengaturan dasar. Tambahkan variabel batas halaman pada app.py.

1
# Default setting

2
pageLimit = 2

Buat fungsi python getWish menerima request POST.

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

Baca offset dan limit di dalam fungsi getWish dan lemparkan ke stored procedure MySQL sp_GetWishByUser.

1
 _limit = pageLimit
2
 _offset = request.form['offset']
3
4
5
con = mysql.connect()
6
cursor = con.cursor()
7
cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset))
8
wishes = cursor.fetchall()
9
10

Ubah fungsi JavaScript GetWishes di userHome.html untuk membuatnya menjadi request POST dan melempar nilai offset.

1
function GetWishes() {
2
    $.ajax({
3
        url: '/getWish',
4
        type: 'POST',
5
        data: {
6
            offset: 0
7
        },
8
        success: function(res) {
9
10
            var wishObj = JSON.parse(res);
11
            $('#ulist').empty();
12
            $('#listTemplate').tmpl(wishObj).appendTo('#ulist');
13
14
        },
15
        error: function(error) {
16
            console.log(error);
17
        }
18
    });
19
}

Simpan semua perubahan dan restart server. Sign in menggunakan email dan password yang sah dan kamu seharusnya hanya melihat dua butir ditampilkan di layar.

User Home with Limited recordsUser Home with Limited recordsUser Home with Limited records

Artinya bagian database bekerja dengan baik. Lalu kita perlu menambahkan antarmuka pagination ke halaman beranda user, yang membuat user bisa menjelajah data.

Kita gunakan komponen pagination dari Bootstrap. Buka userHome.html dan tambahkan kode HTML setelah UL #ulist.

1
<nav>
2
    <ul class="pagination">
3
        <li>
4
            <a href="#" aria-label="Previous">
5
                <span aria-hidden="true">&laquo;</span>
6
            </a>
7
        </li>
8
        <li><a href="#">1</a>
9
        </li>
10
        <li><a href="#">2</a>
11
        </li>
12
        <li><a href="#">3</a>
13
        </li>
14
        <li><a href="#">4</a>
15
        </li>
16
        <li><a href="#">5</a>
17
        </li>
18
        <li>
19
            <a href="#" aria-label="Next">
20
                <span aria-hidden="true">&raquo;</span>
21
            </a>
22
        </li>
23
    </ul>
24
</nav>

Simpan perubahan dan restart server. Setelah sign in dengan sukses, kamu bisa melihat pagination di bawah daftar keinginan.

Pagination in User Home PagePagination in User Home PagePagination in User Home Page

Membuat Pagination Dinamis

Pagination kita akan terlihat seperti di atas. Untuk membuatnya berfungsi, kita perlu membuat pagination dinamis berdasarkan jumlah butir di database.

Untuk membuat pagination kita, kita butuh total butir yang ada dalam database. Kita modifikasi stored procedure sp_GetWishByUser untuk mengembalikan total butir yang tersedia sebagai parameter keluaran.

1
USE `BucketList`;
2
DROP procedure IF EXISTS `sp_GetWishByUser`;
3
4
DELIMITER $$
5
USE `BucketList`$$
6
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_GetWishByUser`(
7
IN p_user_id bigint,
8
IN p_limit int,
9
IN p_offset int,
10
out p_total bigint
11
)
12
BEGIN
13
    
14
	select count(*) into p_total from tbl_wish where wish_user_id = p_user_id;
15
16
	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);
17
	PREPARE stmt FROM @t1;
18
	EXECUTE stmt;
19
	DEALLOCATE PREPARE stmt;
20
END$$
21
22
DELIMITER ;

Seperti yang terlihat pada stored procedure, kita menambahkan parameter output bernama p_total, dan memilih jumlah total keinginan berdasarkan id user.

Kita juga perlu mengubah fungsi python getWish untuk melempar parameter output.

1
 _limit = pageLimit
2
 _offset = request.form['offset']
3
 _total_records = 0
4
5
6
con = mysql.connect()
7
cursor = con.cursor()
8
cursor.callproc('sp_GetWishByUser',(_user,_limit,_offset,_total_records))
9
wishes = cursor.fetchall()
10
11
cursor.close()
12
13
cursor = con.cursor()
14
cursor.execute('SELECT @_sp_GetWishByUser_3');
15
16
outParam = cursor.fetchall()

Seperti yang bisa kamu lihat di kode di atas, setelah kita memanggil stored procedure kita tutup kursor dan buka sebuah kursor baru untuk memilih parameter keluaran yang perlu kita kembalikan.

Sebelumnya, kita mengembalikan daftar keinginan dari fungsi Python. Sekarang, kita perlu memasukkan jumlah butir ke dalam JSON kembalian. Jadi kita buat kamus daftar keinginan ke daftar lain, dan tambahkan daftar keinginan dan jumlah butir ke daftar utama. Berikut adalah kode fungsi python getWish yang sudah diubah.

1
response = []
2
wishes_dict = []
3
4
for wish in wishes:
5
    wish_dict = {
6
        'Id': wish[0],
7
        'Title': wish[1],
8
        'Description': wish[2],
9
        'Date': wish[4]}
10
    wishes_dict.append(wish_dict)
11
    
12
response.append(wishes_dict)
13
response.append({'total':outParam[0][0]}) 
14
15
return json.dumps(response)

Pada fungsi JavaScript GetWishes, di dalam kondisi sukses tambahkan log konsol.

1
console.log(res);

Simpan semua perubahan dan restart server. Sign in menggunakan email dan password yang sah lalu saat di halaman beranda user, periksa konsol browser. Kamu akan lihat respon seperti di bawah ini:

1
[
2
    [{
3
        "Date": "Sun, 15 Feb 2015 15:10:45 GMT",
4
        "Description": "wwe",
5
        "Id": 5,
6
        "Title": "wwe"
7
    }, {
8
        "Date": "Sat, 24 Jan 2015 00:13:50 GMT",
9
        "Description": "Travel to Spain",
10
        "Id": 4,
11
        "Title": "Spain"
12
    }], {
13
        "total": 5
14
    }
15
]

Dengan total butir yang didapat dari respon, kita bisa mendapatkan total halaman yang dibutuhkan.

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

Membagi total butir dengan itemsPerPage memberikan kita jumlah halaman yang dibutuhkan. Ini hanya benar saat total butir adalah kelipatan itemsPerPage. Jika tidak, kita harus periksa dan tangani jumlah halaman yang seharusnya.

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

Kode tersebut akan memberi kita jumlah halaman yang tepat.

Sekarang karena kita sudah memiliki nilai total halaman, kita buat pagination HTML secara dinamis. Hapus elemen LI dari pagination HTML yang kita tambahkan sebelumnya.

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

4
    </ul>

5
</nav>

Pada kondisi sukses GetWishes, buat tautan sebelumnya secara dinamis menggunakan jQuery.

1
var prevLink = $('<li/>').append($('<a/>').attr({
2
        'href': '#'
3
    }, {
4
        'aria-label': 'Previous'
5
    })
6
    .append($('<span/>').attr('aria-hidden', 'true').html('&laquo;')));
7
8
$('.pagination').append(prevLink);

Pada kode di atas, kita membuat tombol tautan sebelumnya dan menambahkannya ke pagination UL.

Simpan perubahan di atas dan restart server. Saat sign in sukses, kamu akan bisa lihat tautan sebelumnya di bawah daftar.

Previous link in the PaginationPrevious link in the PaginationPrevious link in the Pagination

Dengan cara yang serupa kita tambahkan tautan halaman pada pagination berdasarkan jumlah halaman.

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

Kita tambahkan juga tautan berikutnya setelah semua tautan halaman ditambahkan.

1
var nextLink = $('<li/>').append($('<a/>').attr({
2
        'href': '#'
3
    }, {
4
        'aria-label': 'Next'
5
    })
6
    .append($('<span/>').attr('aria-hidden', 'true').html('&raquo;')));
7
8
$('.pagination').append(nextLink);

Simpan perubahan dan restart server. Sign in menggunakan email dan password yang sah, dan di halaman beranda user kamu akan lihat pagination.

Pagination in User Home PagePagination in User Home PagePagination in User Home Page

Menambahkan Event Klik pada Nomor Halaman

Sekarang kita tiba ke logika utama yang membuat pagination kita berfungsi. Yang akan kita lakukan adalah menambahkan event call klik untuk setiap indeks halaman untuk memanggil fungsi JavaScript GetWishes. Kita tambahkan event klik ke elemen tautan yang menampilkan nomor halaman.

1
for (var i = 0; i < pageCount; i++) {
2
3
    var aPage = $('<a/>').attr('href', '#').text(i + 1);
4
  
5
    $(aPage).click(function() {
6
        
7
    });
8
  
9
    var page = $('<li/>').append(aPage);
10
    $('.pagination').append(page);
11
12
}

Kita sudah menambahkan event onclick pada tautan halaman. Untuk setiap klik kita panggil fungsi GetWishes dan melempar offset. Jadi deklarasikan offset di luar loop for.

1
var offset = 0;

Panggil fungsi GetWishes di dalam event call click.

1
GetWishes(offset);

Tambahkan juga offset berdasarkan jumlah butir yang ditampilkan.

1
offset = offset + 2;

Tapi setiap fungsi GetWishes dipanggil, nilai offset akan selalu jadi nilai yang terakhir diatur. Kita akan gunakan JavaScript Closures untuk melempar offset yang tepat untuk fungsi GetWishes.

1
var offset = 0;
2
3
for (var i = 0; i < pageCount; i++) {
4
5
    var aPage = $('<a/>').attr('href', '#').text(i + 1);
6
  
7
    $(aPage).click(function(offset) {
8
        return function() {
9
            GetWishes(offset);
10
        }
11
    }(offset));
12
  
13
    var page = $('<li/>').append(aPage);
14
    $('.pagination').append(page);
15
    offset = offset + itemsPerPage;
16
17
}

Simpan semua perubahan di atas dan restart server. Sign in menggunakan email dan password yang sah, dan pada halaman beranda user, coba klik nomor halaman pada antarmuka pagination.

Berikutnya, kita implemen tautan halaman sebelum dan sesudah. Hal ini mungkin terlihat sedikit rumit, saya akan jelaskan sedikit sebelum mulai kita implementasi.

Kita akan menampilkan lima halaman sekaligus. User bisa berpindah ke lima halaman berikutnya, dan lima halaman sebelumnya menggunakan tautan maju dan mundur. Kita simpan nilai halaman awal dan akhir dan terus memperbarui keduanya saat user menekan tombol mundur dan maju. Kita mulai dengan menambahkan dua nilai tersembunyi pada halaman userHome.html.

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

Pada kondisi sukses GetWishes, setelah kita mengosongkan UL .pagination, tambahkan kode berikut untuk mendapatkan nilai terbaru halaman awal dan akhir.

1
$('.pagination').empty();
2
3
var pageStart = $('#hdnStart').val();
4
var pageEnd = $('#hdnEnd').val();

Tidak ada tombol tautan mundur yang akan ditampilkan saat menampilkan halaman 1 sampai 5. Jika halaman yang ditampilkan lebih besar dari 5 maka kita akan tampilkan tombol tautan mundur.

1
if (pageStart > 5) {
2
    var aPrev = $('<a/>').attr({
3
            'href': '#'
4
        }, {
5
            'aria-label': 'Previous'
6
        })
7
        .append($('<span/>').attr('aria-hidden', 'true').html('&laquo;'));
8
9
    $(aPrev).click(function() {
10
        // Previous button logic

11
    });
12
13
    var prevLink = $('<li/>').append(aPrev);
14
    $('.pagination').append(prevLink);
15
}

Saat user menekan tombol mundur, kita reset nilai hdnStart dan hdnEnd dan panggil fungsi JavaScript GetWishes.

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

Lalu, berdasarkan halaman awal dan akhir, kita buat loop dan buat tautan halaman dan menambahkan UL .pagination.

1
for (var i = Number(pageStart); i <= Number(pageEnd); i++) {
2
3
    if (i > pageCount) {
4
        break;
5
    }
6
7
8
    var aPage = $('<a/>').attr('href', '#').text(i);
9
    
10
    // Attach the page click event

11
    $(aPage).click(function(i) {
12
        return function() {
13
            GetWishes(i);
14
        }
15
    }(i));
16
    
17
    var page = $('<li/>').append(aPage);
18
19
    // Attach the active page class

20
    if ((_page) == i) {
21
        $(page).attr('class', 'active');
22
    }
23
24
    $('.pagination').append(page);
25
26
27
}

Dengan membandingkan jumlah total halaman dan nilai halaman awal, kita tentukan tampilan tombol tautan berikutnya.

1
if ((Number(pageStart) + 5) <= pageCount) {
2
    var nextLink = $('<li/>').append($('<a/>').attr({
3
            'href': '#'
4
        }, {
5
            'aria-label': 'Next'
6
        })
7
        .append($('<span/>').attr('aria-hidden', 'true').html('&raquo;').click(function() {
8
            $('#hdnStart').val(Number(pageStart) + 5);
9
            $('#hdnEnd').val(Number(pageStart) + 5 + 4);
10
            GetWishes(Number(pageStart) + 5);
11
12
        })));
13
    $('.pagination').append(nextLink);
14
}

Seperti yang terlihat di kode di atas, saat user menekan tombol berikutnya kita mereset nilai hdnStart dan hdnEnd dan memanggil fungsi JavaScript GetWishes.

Ini adalah fungsi JavaScript GetWishes yang terkini.

1
function GetWishes(_page) {
2
3
    var _offset = (_page - 1) * 2;
4
  
5
    $.ajax({
6
        url: '/getWish',
7
        type: 'POST',
8
        data: {
9
            offset: _offset
10
        },
11
        success: function(res) {
12
13
            var itemsPerPage = 2;
14
15
            var wishObj = JSON.parse(res);
16
17
            $('#ulist').empty();
18
            $('#listTemplate').tmpl(wishObj[0]).appendTo('#ulist');
19
20
            var total = wishObj[1]['total'];
21
            var pageCount = total / itemsPerPage;
22
            var pageRem = total % itemsPerPage;
23
            if (pageRem != 0) {
24
                pageCount = Math.floor(pageCount) + 1;
25
            }
26
27
28
            $('.pagination').empty();
29
30
            var pageStart = $('#hdnStart').val();
31
            var pageEnd = $('#hdnEnd').val();
32
33
34
35
36
            if (pageStart > 5) {
37
                var aPrev = $('<a/>').attr({
38
                        'href': '#'
39
                    }, {
40
                        'aria-label': 'Previous'
41
                    })
42
                    .append($('<span/>').attr('aria-hidden', 'true').html('&laquo;'));
43
44
                $(aPrev).click(function() {
45
                    $('#hdnStart').val(Number(pageStart) - 5);
46
                    $('#hdnEnd').val(Number(pageStart) - 5 + 4);
47
                    GetWishes(Number(pageStart) - 5);
48
                });
49
50
                var prevLink = $('<li/>').append(aPrev);
51
                $('.pagination').append(prevLink);
52
            }
53
54
55
56
            for (var i = Number(pageStart); i <= Number(pageEnd); i++) {
57
58
                if (i > pageCount) {
59
                    break;
60
                }
61
62
63
                var aPage = $('<a/>').attr('href', '#').text(i);
64
65
                $(aPage).click(function(i) {
66
                    return function() {
67
                        GetWishes(i);
68
                    }
69
                }(i));
70
                var page = $('<li/>').append(aPage);
71
72
                if ((_page) == i) {
73
                    $(page).attr('class', 'active');
74
                }
75
76
                $('.pagination').append(page);
77
78
79
            }
80
            if ((Number(pageStart) + 5) <= pageCount) {
81
                var nextLink = $('<li/>').append($('<a/>').attr({
82
                        'href': '#'
83
                    }, {
84
                        'aria-label': 'Next'
85
                    })
86
                    .append($('<span/>').attr('aria-hidden', 'true').html('&raquo;').click(function() {
87
                        $('#hdnStart').val(Number(pageStart) + 5);
88
                        $('#hdnEnd').val(Number(pageStart) + 5 + 4);
89
                        GetWishes(Number(pageStart) + 5);
90
91
                    })));
92
                $('.pagination').append(nextLink);
93
            }
94
95
96
97
98
        },
99
        error: function(error) {
100
            console.log(error);
101
        }
102
    });
103
}

Simpan semua perubahan di atas dan restart server. Sign in menggunakan email dan password yang sah. Kamu bisa lihat fungsi pagination untuk daftar keinginan user.

Kesimpulan

Pada bagian ini dari seri tutorial, kita membuat fitur pagination untuk daftar keinginan pada halaman beranda user. Kita lihat bagaimana cara mendapatkan data menggunakan stored procedure MySQL dan membuat pagination menggunakan data tersebut, jQuery, dan Bootstrap.

Pada bagian berikutnya dari seri tutorial ini, kita akan implementasi fitur upload file ke aplikasi kita.

Source code untuk tutorial ini tersedia di GitHub.

Beri tahu kami pendapatmu di komentar di bawah!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.