Lập trình web với Python và Flask Framework

Khi nói tới lập trình web thì có lẽ rất nhiều lập trình viên sẽ liên tưởng ngay tới ngôn ngữ php. Ngôn ngữ php được biết tới là ngôn ngữ được sinh ra để phục vụ cho việc làm web với rất nhiều framework, cms cộng thêm với một cộng đồng rất đông và hung hãn nhưng trong bài viết tôi muốn trình bày một tiếp cận khác, bằng ngôn ngữ khác cho công cuộc làm web đó là lập trình web với ngôn ngữ python.

I. Xây dựng môi trường

Lựa chọn framework:  Hiện tại có rất nhiều framework hỗ trợ lập trình web bằng ngôn ngữ python trong đó có 3 cái tên đó là Django, Flask, Pyramid ... mỗi framework đều có điểm mạnh và điểm yếu riêng của nó, để hiểu chi tiết hơn hãy tham khảo phần "Link tham khảo" ở phần cuối của bài viết này. Trong ví dụ này tôi giới thiệu về framework Flask (Flask là một microframework cho Python dựa trên Werkzeug, Jinja 2)

Cài đặt framework Flask:

Cài đặt python và pid như link sau:

https://docs.python-guide.org/starting/install3/osx/

Cài đặt Flask

pip install flask

Tạo thư mục của dự án:

mkdir hoctiengnhatonline

Tạo một file khởi tạo app.py trong thư mục "hoctiengnhatonline", sau đó cấu hình để sử dụng module Flask trong file app.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def main():
  return "Welcome"

if __name__ == "__main__":
  app.run()

Thực thi app.py

python app.py

Vào trình duyệt và truy cập đường link dưới đây
http://localhost:5000/

II. Tạo trang chủ

Trong thư mục hoctiengnhatonline tạo thư mục templates, trong thư mục templates tạo một file đặt tên là index.html, mở file index.html thêm đoạn code HTML sau đây vào:

<!DOCTYPE html>
<html lang="en">
 
<head>
    <title>Hoc Tieng Nhat Online App</title>
 
 
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
 
    <link href="https://hroy.eu/bootstrap/docs/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
 
 
</head>
 
<body>
 
    <div class="container">
        <div class="header">
            <nav>
                <ul class="nav nav-pills pull-right">
                    <li role="presentation" class="active"><a href="#">Home</a>
                    </li>
                    <li role="presentation"><a href="#">Sign In</a>
                    </li>
                    <li role="presentation"><a href="showSignUp">Sign Up</a>
                    </li>
                </ul>
            </nav>
            <h3 class="text-muted">Hoc tieng Nhat online App</h3>
        </div>
 
        <div class="jumbotron">
            <h1>Japanese Lesson App</h1>
            <p class="lead"></p>
            <p><a class="btn btn-lg btn-success" href="showSignUp" role="button">Sign up today</a>
            </p>
        </div>
 
        <div class="row marketing">
            <div class="col-lg-6">
                <h4>Lesson List</h4>
                <p>Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List</p>

                <h4>Lesson List</h4>
                <p>Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List</p>

                <h4>Lesson List</h4>
                <p>Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List</p>
            </div>
 
            <div class="col-lg-6">
                <h4>Lesson List</h4>
                <p>Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List</p>

                <h4>Lesson List</h4>
                <p>Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List</p>

                <h4>Lesson List</h4>
                <p>Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List Lesson List</p>
            </div>
        </div>
 
        <footer class="footer">
            <p>&copy; Copyright 2019</p>
        </footer>
 
    </div>
</body>
 
</html>

Mở app.pyimport render_template, cái mà chúng ta sẽ sử dụng để kết xuất các tập tin template.

from flask import Flask, render_template

Sửa phương thức chính để trả về tập tin template đã được kết xuất.

def main():
    return render_template('index.html')

Mở trình duyệt và truy cập http://localhost:5000/ và sẽ thấy màn hình dưới đây:

III. Tạo trang đăng ký

Bước 1: Tạo Database

Tạo database tên là hoctiengnhatonline

CREATE DATABASE hoctiengnhatonline;

Tạo bảng lưu người dùng tbl_user

CREATE TABLE `hoctiengnhatonline`.`tbl_user` (
  `user_id` BIGINT AUTO_INCREMENT,
  `user_name` VARCHAR(45) NULL,
  `user_username` VARCHAR(45) NULL,
  `user_password` VARCHAR(45) NULL,
  PRIMARY KEY (`user_id`));

Tạo thủ tục để lưu thông tin người dùng đặt tên là sp_createUser

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_createUser`(
    IN p_name VARCHAR(20),
  IN p_username VARCHAR(20),
    IN p_password VARCHAR(20)
)
BEGIN
    if ( select exists (select 1 from tbl_user where user_username = p_username) ) THEN
     
        select 'Username Exists !!';
     
    ELSE
     
        insert into tbl_user
        (
            user_name,
            user_username,
            user_password
        )
        values
        (
            p_name,
            p_username,
            p_password
        );
     
    END IF;
END$$
DELIMITER ;

Bước 2: Tạo giao diện đăng ký

Trong thư mục hoctiengnhatonline/templates tạo một file HTML đặt tên là signup.html, sau đó chèn đoạn code dưới đây vào tập tin signup.html

<!DOCTYPE html>
<html lang="en">
<head>
   <title>Hoc Tieng Nhat Online App</title>

   <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet">
   <link href="https://hroy.eu/bootstrap/docs/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
   <link href="../static/signup.css" rel="stylesheet">

</head>

<body>

<div class="container">
   <div class="header">
       <nav>
           <ul class="nav nav-pills pull-right">
               <li role="presentation" ><a href="main">Home</a></li>
               <li role="presentation"><a href="#">Sign In</a></li>
               <li role="presentation" class="active"><a href="#">Sign Up</a></li>
           </ul>
       </nav>
       <h3 class="text-muted">Hoc tieng Nhat online App</h3>
   </div>

   <div class="jumbotron">
       <h1>Học tiếng Nhật Online App</h1>
       <form class="form-signin">
           <label for="inputName" class="sr-only">Name</label>
           <input type="name" name="inputName" id="inputName" class="form-control" placeholder="Name" required autofocus>
           <label for="inputEmail" class="sr-only">Email address</label>
           <input type="email" name="inputEmail" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
           <label for="inputPassword" class="sr-only">Password</label>
           <input type="password" name="inputPassword" id="inputPassword" class="form-control" placeholder="Password" required>

           <button id="btnSignUp" class="btn btn-lg btn-primary btn-block" type="button">Sign up</button>
       </form>
   </div>



   <footer class="footer">
       <p>&copy; Copyright 2019</p>
   </footer>

</div>
</body>
</html>

Tạo thêm file CSS trong thư mục static bên trong hoctiengnhatonline

body {
 padding-top: 40px;
 padding-bottom: 40px;
}

.form-signin {
 max-width: 330px;
 padding: 15px;
 margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
 margin-bottom: 10px;
}
.form-signin .checkbox {
 font-weight: normal;
}
.form-signin .form-control {
 position: relative;
 height: auto;
 -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
         box-sizing: border-box;
 padding: 10px;
 font-size: 16px;
}
.form-signin .form-control:focus {
 z-index: 2;
}
.form-signin input[type="email"] {
 margin-bottom: -1px;
 border-bottom-right-radius: 0;
 border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
 margin-bottom: 10px;
 border-top-left-radius: 0;
 border-top-right-radius: 0;
}

Thêm đoạn code sau vào trong file app.py

@app.route('/showSignUp')
def showSignUp():
   return render_template('signup.html')

Nhập chuột vào nút SignUp màn hình dưới đây được hiển thị:

Bước 3: Tạo phương thức đăng ký

Thêm đoạn code xử lý đăng ký signUp và import thêm thư viện vào file app.py

@app.route('/signUp',methods=['POST'])
def signUp():
 
    # read the posted values from the UI
    _name = request.form['inputName']
    _email = request.form['inputEmail']
    _password = request.form['inputPassword']
 
    # validate the received values
    if _name and _email and _password:
        return json.dumps({'html':'<span>All fields good !!</span>'})
    else:
        return json.dumps({'html':'<span>Enter the required fields</span>'})

from flask import Flask, render_template, json, request

Bước 4: Tạo đăng ký từ client

$(function() {
    $('#btnSignUp').click(function() {
        $.ajax({
            url: '/signUp',
            data: $('form').serialize(),
            type: 'POST',
            success: function(response) {
                console.log(response);
            },
            error: function(error) {
                console.log(error);
            }
        });
    });
});

Bước 5: Lưu thông tin bằng thủ tục của Mysql

Đầu tiên cài đặt thư viện mysql cho flask bằng lệnh sau:

pip install flask-mysql

Trong file app.py import thêm thư viện và thêm các đoạn code xử lý sau vào

from flask import Flask, render_template, json, request
from flaskext.mysql import MySQL
from werkzeug import generate_password_hash, check_password_hash

mysql = MySQL()
app = Flask(__name__)

# MySQL configurations
app.config['MYSQL_DATABASE_USER'] = 'root'
app.config['MYSQL_DATABASE_PASSWORD'] = '12345678'
app.config['MYSQL_DATABASE_DB'] = 'hoctiengnhatonline'
app.config['MYSQL_DATABASE_HOST'] = 'localhost'
mysql.init_app(app)

Trong function xử lý đăng ký thông tin người dùng thêm đoạn code sau:

# validate the received values
if _name and _email and _password:

    # All Good, let's call MySQL
    conn = mysql.connect()
    cursor = conn.cursor()
    _hashed_password = generate_password_hash(_password)
    cursor.callproc('sp_createUser',(_name,_email,_hashed_password))
    data = cursor.fetchall()

    if len(data) is 0:
        conn.commit()
        return json.dumps({'message':'User created successfully !'})
    else:
        return json.dumps({'error':str(data[0])})
else:
    return json.dumps({'html':'<span>Enter the required fields</span>'})

except Exception as e:
    return json.dumps({'error':str(e)})
finally:
    cursor.close() 
    conn.close()

Lưu các thay đổi và khởi động lại máy chủ. Đi đến trang đăng ký và nhập name, emailpassword và nhấp vào nút Sign Up. Khi tạo thành công người dùng, bạn sẽ có thể thấy một thông báo trong giao diện console của trình duyệt.

{"message": "User created successfully !"}

VI. Tổng kết

Trong bài viết này, tôi trình bày cách đơn giản nhất khi lập trình web bằng ngôn ngữ python dùng framework Flask hy vọng sẽ phần nào giúp ích được phần nào đó cho bạn đọc lần đầu lập trình web bằng ngôn ngữ python. Hãy tham khảo toàn bộ source code ở link tham khảo dưới đây. Trong bài viết tiếp theo tôi sẽ trình bày kỹ hơn về các chú ý khi lập trình web bằng python.

V. Link tham khảo

https://pypi.org/project/Flask/1.0.2/

http://flask.pocoo.org/