Hướng dẫn python web form builder - trình tạo biểu mẫu web python
Trong phần này, chúng ta sẽ cùng tìm hiểu về khái niệm Web Form và cách sử dụng Web Form trong Flask. Show Để giúp cho bạn dễ theo dõi, sau đây là danh sách các bài viết trong loạt bài hướng dẫn này:
Bạn có thể truy cập mã nguồn cho phần này tại GitHub. Trong Phần 2, chúng ta đã tạo ra một template đơn giản cho trang chủ của ứng dụng và dùng các đối tượng giả lập cho các thành phần mà chúng ta chưa xây dựng như là đối tượng người sử dụng, các bài viết. Trong chương này, chúng ta sẽ tìm hiểu kỹ hơn về các điểm yếu của ứng dụng cho đến thời điểm này, đặt biệt là vấn đề tiếp nhận và xử lý những yêu cầu của người sử dụng thông qua Web form. Một cách tổng quát, Web form (đừng nhầm lẫn với khái niệm Web form trong các ứng dụng ASP/ASP.NET truyền thống nhé, chúng không có liên quan gì với nhau mặc dù có cùng tên gọi) là một trong những thành phần cơ bản của bất kỳ ứng dụng Web nào. Chúng ta sẽ dùng Web form để người sử dụng có thể gởi dữ liệu như là bài viết, thông tin đăng nhập từ trình duyệt đến ứng dụng của chúng ta. Trước khi bắt đầu phần mới, hãy chắc rằng ứng dụng myblog mà chúng ta đã xây dựng được thiết lập và chạy thành công. Giới thiệu Flask-WTFĐể xử lý Web form trong ứng dụng, chúng ta sẽ dùng thư viện mở rộng (extension) Flask-WTF. Đây là một giao diện cho gói WTForms được tích hợp với Flask. Đây là thư viện mở rộng đầu tiên mà chúng ta sử dụng, nhưng sẽ không phải là cuối cùng. Các thư viện mở rộng là một thành phần quan trọng trong hệ sinh thái của Flask bởi vì chúng cung cấp các giải pháp mà Flask không có (dù là cố tình hay vô ý). Các thư viện mở rộng của Flask là các gói thư viện Python tiêu chuẩn được cài đặt bằng
Thiết lập cấu hìnhCho đến thời điểm này, ứng dụng của chúng ta vẫn còn rất sơ khai, và do đó, chúng ta không cần phải để ý nhiều đến vấn đề cấu hình (configuration). Nhưng đối với bất kỳ ứng dụng nào ngoại trừ các ứng dụng rất đơn giản, chúng ta sẽ thấy rằng Flask (và có thể bao gồm các thư viện mở rộng của Flask mà bạn dùng) cho phép chúng ta tự do trong việc thực hiện ở mức độ nhất định. Và khi bạn cần ra quyết định nào đó, bạn sẽ cho Flask biết thông qua một danh sách các tham số cấu hình. Có một vài định dạng khác nhau trong việc cung cấp cấu hình cho ứng dụng. Giải pháp cơ bản nhất là định nghĩa các tham số cấu hình của bạn qua các khóa (key) trong file
Dù cấu trúc trên đây là đầy đủ cho việc định nghĩa cấu hình cho Flask, chúng ta vẫn nên tuân theo nguyên tắc phân chia các mối quan tâm (separation of concerns). Cụ thể hơn, thay vì đặt tất cả các thông số cấu hình vào trong mã khởi tạo của ứng dụng, chúng ta sẽ đặt nó vào một file cấu hình riêng rẽ. Trong khuôn khổ loạt bài này, chúng ta sẽ theo quy ước là dùng một class để chứa tất cả các thông số cấu hình của ứng dụng. Để giữ cho cấu trúc chung của ứng dụng được gọn gàng, chúng ta sẽ tạo ra lớp cấu hình trong một module Python riêng biệt. Sau đây là các khai báo trong lớp cấu hình cho ứng dụng trong file config.py mà chúng ta sẽ lưu ở thư mục ngoài cùng của ứng dụng: config.py: Cấu hình cho mã khóa: Cấu hình cho mã khóa
Rất đơn giản phải không? Tham số cấu hình sẽ được định nghĩa là các biến bên trong lớp Tham số cấu hình Giá trị của khóa bí mật này là một biểu thức với hai mệnh đề được ghép lại với nhau qua toán tử OR. Mệnh đề thức nhất sẽ tìm giá trị của một biến môi trường cũng gọi là Sau khi đã có file cấu hình, chúng ta cần cho Flask biết để lấy thông tin từ đó và dùng cho ứng dụng. Chúng ta làm điều này bằng cách cập nhật file __init__.py và thêm một dòng lệnh sử dụng hàm app/__init__.py: cấu hình Flask cấu hình Flask
Thoạt nhìn thì cách tham chiếu đến lớp Như đã nói ở trên, các tham số cấu hình sẽ được truy cập qua từ điển trong
Thư viện mở rộng (Flask-WTF) sử dụng các lớp trong Python để đại diện cho các Web form. Các lớp này – gọi tắt là lớp form) sẽ định nghĩa các trường (field) có trên form qua các biến thành viên. Theo đúng nguyên tắc phân chia các mối quan tâm đã được đề cập ở trên, chúng ta sẽ tạo ra một module mới trong thư mục app có tên là forms.py để chứa các thông tin về form đăng nhập của chúng ta. Chúng ta bắt đầu với một form đơn giản bao gồm hai khung nhập văn bản (text box) để người sử dụng có thể nhập vào tên người sử dụng và mật khẩu (username và password). Form này cũng có thêm một khung đánh dấu (checkbox) tên là “Remember me” và một nút bấm để gởi thông tin đăng nhập từ trình duyệt của người sử dụng về ứng dụng trên máy chủ (submit button). app/forms.py: form đăng nhập form đăng nhập
Đa số các thư viện mở rộng của Flask dùng quy ước Ứng dụng của chúng ta cũng sử dụng bốn lớp khác từ gói WTForms để đại diện cho các trường nhập dữ liệu tương ứng. Mỗi một trường sẽ được đại diện bởi một biến trong lớp Template cho FormBước tiếp theo là tạo một HTML template sử dụng form của chúng ta. Việc tạo template này không quá phức tạp vì các trường được định nghĩa trong lớp LoginForm biết cách để tạo ra mã HTML cho chính chúng. Sau đây là đoạn mã để tạo ra template đăng nhập, chúng ta sẽ đặt mã này vào file app/templates/login.html: app/templates/login.html: template cho form đăng nhập template cho form đăng nhập
Mẫu trong nÀy chún ta sẽ sử dụng lại mẫu cơ sở.html ĐượC GIớI THIệU TRONG PHầN 2 BằNG C ấu cấu trúc này Cho tất cả cau mẫu MớI Mẫu NÀY Cần Có Một Tham Số Là MộT Th Tham Số NÀY CầN ĐượC TRUYềN Từ HÀM HIểN Th Thẻ html Tham Số Nếu bạn Đạo từng viết Html Web Form, Có Thể BạN Sẽ Th Lý do là vì Đối tượng hình thức mà chún ta khai báio trong forms. Việc chún ta cần lào là Nếu đó là trường nào cần bạn thne nh ững thu Ví dụ như khi bạn khởi tạo các Đối tượng tên người dùng và mật khẩu, bạn bạn thể thênm vào Thams số Hiển thị FormChún ta đã lào hầu hết các bước Để tạo ra mẫu ĐĂng NHập (đăng nhập). TUy Nhiênn, Để Hiển thị Form nÀy trong trình diyệt, chúnt ta Khi bạn Chúnt ta app/routes.py: Hàm hiển thị cho form Login Hàm hiển thị cho form Login
Ở đây, chúng ta thêm tham chiếu đến lớp Để giúp cho việc truy cập form Login dễ dàng hơn, chúng ta sẽ thay đổi một chút thanh định hướng ở template base.html: app/templates/base.html: Liên kết đến trang Login trong thanh định hướng: Liên kết đến trang Login trong thanh định hướng:
Đến đây, bạn có thể chạy thử ứng dụng một lần nữa và kiểm tra form mà chúng ta đã tạo ra. Sau khi ứng dụng được kích hoạt, hãy nhập địa chỉ Nhận dữ liệu từ formĐến đây, chúng ta đã có một form đăng nhập thật hấp dẫn. Tuy nhiên, nếu bạn thử bấm vào nút “Sign in”, chúng ta sẽ thấy một thông báo lỗi không mấy dễ chịu: “Method Not Allowed”. Chuyện gì xảy ra ở đây? Lý do là vì hàm hiển thị của chúng ta mới chỉ làm có một nửa chuyện mà nó cần làm: nó hiển thị form nhưng hoàn toàn không có mã lệnh nào để làm công việc xử lý dữ liệu nhận được khi người dùng bấm nút gởi (submit) dữ liệu – nút “Sign in” trên form của chúng ta. Tiếp theo, chúng ta sẽ cập nhật hàm hiển thị để nhận và kiểm tra dữ liệu do người sử dụng nhập vào form như sau: app/routes.py: Nhận thông tin người sử dụng Nhận thông tin người sử dụng
Ở đây, chúng ta thêm tham chiếu đến lớp Để giúp cho việc truy cập form Login dễ dàng hơn, chúng ta sẽ thay đổi một chút thanh định hướng ở template base.html: app/templates/base.html: Liên kết đến trang Login trong thanh định hướng:Sign in”, trình duyệt sẽ
gởi yêu cầu dưới dạng Tiếp theo, khi hàm Hàm thứ nhì được gọi trong hàm hiển thị là Khi bạn gọi hàm app/templates/base.html: Hiển thị thông điệp được truyền vào hàm flash() Hiển thị thông điệp được truyền vào hàm flash()
{% if title %} {{ title }} - Myblog {% else %}Sign in” để gởi dữ liệu về máy chủ nhưng chừa trống trường “username” hoặc “password”, làm như vậy bạn sẽ thấy cách hoạt động của các biến kiểm tra dữ liệu {% endif %}{% with messages = get_flashed_messages() %} Nếu bạn cố submit dữ liệu không hợp lệ với form login của chúng ta, có lẽ bạn sẽ để ý thấy rằng dù form hoạt động đúng theo ý đồ của chúng ta (hiển thị lại form với các dữ liệu nhập để bạn sửa đổi), nhưng không có gợi ý gì trên form để cho bạn biết dữ liệu nào sai hoặc thiếu và cần được sửa đổi. Vì vậy chúng ta có thể cải tiến mã của chúng ta để đưa ra các thông báo lỗi thích hợp và giúp cho người dùng dễ dàng nhận ra dữ liệu không hợp lệ. Thật ra thì khi có dữ liệu không hợp lệ, các biến kiểm tra dữ liệu đã sinh ra các thông báo lỗi rồi, điều chúng ta cần làm là thêm một vài dòng lệnh để hiển thị các thông báo lỗi này mà thời. Sau đây là phiên bản mới của template login với các thông báo lỗi cho các trường username và password: app/templates/login.html: Thông báo lỗi nhập liệu trong template Login Thông báo lỗi nhập liệu trong template Login
{% for error in form.password.errors %} {{ form.remember_me() }} {{ form.remember_me.label }}{{ form.submit() }}
Thay đổi duy nhất mà chúng ta đã làm ở đây là thêm một vòng lặp ngay sau mã cho các trường username và password để hiển thị các thông báo lỗi sinh ra bởi biến kiểm tra bằng màu đỏ. Theo quy ước, các thông báo lỗi cho các trường có liên kết với biến kiểm tra dữ liệu sẽ được thêm vào biến
Tạo liên kết (link) Đến đây thì form login gần như hoàn tất. Nhưng trước khi kết thúc phần này, chúng ta sẽ nói qua một chút về cách đặt các liên kết (link) và chuyển trang (redirect). Cho đến giờ, bạn đã thấy một số trường hợp chúng ta đặt các liên kết vào ứng dụng. Ví dụ như trong thanh định hướng ở template base.html: Hàm hiển thị cho trang login cũng có một liên kết dưới dạng tham số cho hàm Vì thế, từ bây giờ chúng ta sẽ tập làm quen bằng cách sử dụng hàm app/templates/base.html: Sử dụng hàm
Và cuối cùng là hàm hiển thị login() sử dụng hàm url_for: app/routes.py: Sử dụng hàm
Đến đây, chúng ta có thể chạy thử lần nữa và lần này, bạn hãy thử nhập vào đầy đủ username, password và sau cùng, bấm nút “Sign In“. Bạn sẽ thấy kết quả tương tự như sau:Sign In“. Bạn sẽ thấy kết quả tương tự như sau: Xin chúc mừng, bạn đã thành công tạo ra form đăng nhập đầu tiên. Chúng ta sẽ kết thúc ở đây, hẹn gặp lại bạn trong phần tiếp theo. |