Thứ hai, 22/06/2020 | 00:00 GMT+7

Cách sử dụng mối quan hệ một-nhiều database với Flask và SQLite

Flask là một khuôn khổ để xây dựng các ứng dụng web bằng ngôn ngữ Python và SQLite là một công cụ database được dùng với Python để lưu trữ dữ liệu ứng dụng. Trong hướng dẫn này, bạn sẽ sử dụng Flask với SQLite để tạo ứng dụng việc cần làm, nơi user có thể tạo danh sách các mục việc cần làm. Bạn sẽ học cách sử dụng SQLite với Flask và cách hoạt động của các mối quan hệ database một-nhiều.

 

Mối quan hệ database một -nhiều là mối quan hệ giữa hai bảng database trong đó một bản ghi trong một bảng có thể tham chiếu một số bản ghi trong một bảng khác. Ví dụ: trong một ứng dụng viết blog, một bảng để lưu trữ các bài đăng có thể có mối quan hệ một-nhiều với một bảng để lưu trữ các comment . Mỗi bài đăng có thể tham khảo nhiều comment , và mỗi comment tham chiếu đến một bài đăng; do đó, một bài đăng có mối quan hệ với nhiều comment . Bảng bài đăng là bảng mẹ , trong khi bảng chú thích là bảng con — một bản ghi trong bảng mẹ có thể tham chiếu nhiều bản ghi trong bảng con. Đây là điều quan trọng để có thể có quyền truy cập vào dữ liệu liên quan trong mỗi bảng.

Ta sẽ sử dụng SQLite vì nó có tính di động và không cần cài đặt thêm để hoạt động với Python. Nó cũng tuyệt vời để tạo mẫu một ứng dụng trước khi chuyển sang database lớn hơn như MySQL hoặc Postgres. Để biết thêm về cách chọn hệ thống database phù hợp, hãy đọc bài viết SQLite vs MySQL vs PostgreSQL: A Comparison Of Relational Database Management Systems .

Yêu cầu

Trước khi bắt đầu làm theo hướng dẫn này, bạn cần :

Bước 1 - Tạo database

Trong bước này, bạn sẽ kích hoạt môi trường lập trình của bạn , cài đặt Flask, tạo database SQLite và điền dữ liệu mẫu vào nó. Bạn sẽ học cách sử dụng foreign keys để tạo mối quan hệ một-nhiều giữa danh sách và mục. Khóa ngoại là một khóa dùng để liên kết một bảng database với một bảng khác, nó là liên kết giữa bảng con và bảng cha của nó.

Nếu bạn chưa kích hoạt môi trường lập trình của bạn , hãy đảm bảo bạn đang ở trong folder dự án ( flask_todo ) và sử dụng lệnh này để kích hoạt nó:

  • source env/bin/activate

Khi môi trường lập trình của bạn được kích hoạt, hãy cài đặt Flask bằng lệnh sau:

  • pip install flask

Sau khi cài đặt xong, bây giờ bạn có thể tạo file giản đồ database có chứa các lệnh SQL để tạo các bảng bạn cần để lưu trữ dữ liệu việc cần làm của bạn . Bạn cần hai bảng: một bảng được gọi là lists để lưu trữ danh sách việc cần làm và một bảng items để lưu trữ các mục của mỗi danh sách.

Mở một file có tên schema.sql bên trong folder flask_todo của bạn:

  • nano schema.sql

Nhập các lệnh SQL sau bên trong file này:

flask_todo / schema.sql
DROP TABLE IF EXISTS lists; DROP TABLE IF EXISTS items;  CREATE TABLE lists (     id INTEGER PRIMARY KEY AUTOINCREMENT,     created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,     title TEXT NOT NULL );  CREATE TABLE items (     id INTEGER PRIMARY KEY AUTOINCREMENT,     list_id INTEGER NOT NULL,     created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,     content TEXT NOT NULL,     FOREIGN KEY (list_id) REFERENCES lists (id) ); 

Lưu và đóng file .

Hai lệnh SQL đầu tiên là DROP TABLE IF EXISTS lists;DROP TABLE IF EXISTS items; , các bảng này sẽ xóa mọi bảng hiện có có tên là listsitems để bạn không thấy hành vi khó hiểu. Lưu ý điều này sẽ xóa tất cả nội dung bạn có trong database khi nào bạn sử dụng các lệnh SQL này, vì vậy hãy đảm bảo bạn không viết bất kỳ nội dung quan trọng nào trong ứng dụng web cho đến khi bạn hoàn thành hướng dẫn này và thử nghiệm với kết quả cuối cùng.

Tiếp theo, bạn sử dụng CREATE TABLE lists để tạo bảng lists sẽ lưu trữ danh sách việc cần làm (chẳng hạn như danh sách học tập, danh sách công việc, danh sách nhà, v.v.) với các cột sau:

  • id : Một số nguyên đại diện cho một khóa chính , nó sẽ được database gán một giá trị duy nhất cho mỗi mục nhập (tức là danh sách việc cần làm).
  • created : Thời gian danh sách việc cần làm được tạo lúc. NOT NULL biểu thị rằng cột này không được để trống và giá trị DEFAULT là giá trị CURRENT_TIMESTAMP , là thời điểm danh sách được thêm vào database . Cũng giống như id , bạn không cần chỉ định giá trị cho cột này, vì nó sẽ tự động được điền vào.
  • title : title danh sách.

Sau đó, bạn tạo một bảng có tên là items để lưu trữ các mục việc cần làm. Bảng này có ID, cột số nguyên list_id để xác định mục thuộc về danh sách nào, ngày tạo và nội dung của mục. Để liên kết một mục với một danh sách trong database , bạn sử dụng ràng buộc foreign keys với dòng FOREIGN KEY (list_id) REFERENCES lists (id) . Ở đây bảng lists là một bảng mẹ , là bảng đang được tham chiếu bởi ràng buộc foreign keys , điều này cho biết một danh sách có thể có nhiều mục. Bảng items là bảng con , là bảng mà ràng buộc áp dụng cho. Điều này nghĩa là các mục thuộc về một danh sách duy nhất. Cột list_id tham chiếu đến cột id của bảng mẹ lists .

Vì một danh sách có thể có nhiều mục và một mục chỉ thuộc về một danh sách, mối quan hệ giữa lists và bảng items là mối quan hệ một-nhiều .

Tiếp theo, bạn sẽ sử dụng file schema.sql để tạo database . Mở file có tên init_db.py bên trong folder flask_todo :

  • nano init_db.py

Sau đó thêm mã sau:

flask_todo / init_db.py
import sqlite3  connection = sqlite3.connect('database.db')   with open('schema.sql') as f:     connection.executescript(f.read())  cur = connection.cursor()  cur.execute("INSERT INTO lists (title) VALUES (?)", ('Work',)) cur.execute("INSERT INTO lists (title) VALUES (?)", ('Home',)) cur.execute("INSERT INTO lists (title) VALUES (?)", ('Study',))  cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)",             (1, 'Morning meeting')             )  cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)",             (2, 'Buy fruit')             )  cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)",             (2, 'Cook dinner')             )  cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)",             (3, 'Learn Flask')             )  cur.execute("INSERT INTO items (list_id, content) VALUES (?, ?)",             (3, 'Learn SQLite')             )  connection.commit() connection.close() 

Lưu và đóng file .

Tại đây bạn kết nối với một file có tên là database.db sẽ được tạo sau khi bạn thực thi chương trình này. Sau đó, bạn mở file schema.sql và chạy nó bằng phương thức schema.sql executescript() thực thi nhiều câu lệnh SQL cùng một lúc.

Chạy schema.sql sẽ tạo lists và bảng items . Tiếp theo, sử dụng đối tượng Con trỏ , bạn thực thi một vài INSERT SQL để tạo ba danh sách và năm mục việc cần làm.

Bạn sử dụng cột list_id để liên kết từng mục với danh sách thông qua giá trị id của danh sách. Ví dụ: danh sách Work là phần chèn đầu tiên vào database , vì vậy nó sẽ có ID 1 . Đây là cách bạn có thể liên kết mục việc cần làm của Morning meeting với Work — luật tương tự áp dụng cho các danh sách và mục khác.

Cuối cùng, bạn commit các thay đổi và đóng kết nối.

Chạy chương trình:

  • python init_db.py

Sau khi thực thi, một file mới có tên là database.db sẽ xuất hiện trong folder flask_todo của bạn.

Bạn đã kích hoạt môi trường của bạn , cài đặt Flask và tạo database SQLite. Tiếp theo, bạn sẽ truy xuất danh sách và các mục từ database và hiển thị chúng trong trang chủ của ứng dụng.

Bước 2 - Hiển thị các việc cần làm

Trong bước này, bạn sẽ kết nối database bạn đã tạo ở bước trước với ứng dụng Flask hiển thị danh sách việc cần làm và các mục của mỗi danh sách. Bạn sẽ học cách sử dụng các phép nối SQLite để truy vấn dữ liệu từ hai bảng và cách group các mục việc cần làm theo danh sách của chúng.

Đầu tiên, bạn sẽ tạo file ứng dụng. Mở file có tên app.py bên trong folder flask_todo :

  • nano app.py

Và sau đó thêm mã sau vào file :

flask_todo / app.py
from itertools import groupby import sqlite3 from flask import Flask, render_template, request, flash, redirect, url_for   def get_db_connection():     conn = sqlite3.connect('database.db')     conn.row_factory = sqlite3.Row     return conn   app = Flask(__name__) app.config['SECRET_KEY'] = 'this should be a secret random string'   @app.route('/') def index():     conn = get_db_connection()     todos = conn.execute('SELECT i.content, l.title FROM items i JOIN lists l \                           ON i.list_id = l.id ORDER BY l.title;').fetchall()      lists = {}      for k, g in groupby(todos, key=lambda t: t['title']):         lists[k] = list(g)      conn.close()     return render_template('index.html', lists=lists) 

Lưu và đóng file .

Các get_db_connection() chức năng mở một kết nối đến database.db file database và sau đó đặt row_factory thuộc tính để sqlite3.Row . Bằng cách này, bạn có thể có quyền truy cập dựa trên tên vào các cột; điều này nghĩa là kết nối database sẽ trả về các hàng hoạt động giống như từ điển Python thông thường. Cuối cùng, hàm trả về đối tượng kết nối conn mà bạn sẽ sử dụng để truy cập database .

Trong hàm xem index() , bạn mở kết nối database và thực hiện truy vấn SQL sau:

SELECT i.content, l.title FROM items i JOIN lists l ON i.list_id = l.id ORDER BY l.title; 

Sau đó, bạn truy xuất kết quả của nó bằng cách sử dụng phương thức fetchall() và lưu dữ liệu vào một biến có tên là todos .

Trong truy vấn này, bạn sử dụng SELECT để lấy nội dung của mục và tiêu đề của danh sách mà nó thuộc về bằng cách kết hợp cả bảng items và bảng lists (với alias bảng là i cho itemsl cho lists ). Với điều kiện i.list_id = l.id sau từ khóa ON , bạn sẽ nhận được từng hàng từ bảng items với mọi hàng từ bảng lists trong đó cột list_id của bảng items trùng với id của bảng lists . Sau đó, bạn sử dụng ORDER BY để sắp xếp kết quả theo tiêu đề danh sách.

Để hiểu rõ hơn truy vấn này, hãy mở Python REPL trong folder flask_todo của bạn:

  • python

Để hiểu truy vấn SQL, hãy kiểm tra nội dung của biến todos bằng cách chạy chương trình nhỏ này:

  • from app import get_db_connection
  • conn = get_db_connection()
  • todos = conn.execute('SELECT i.content, l.title FROM items i JOIN lists l \
  • ON i.list_id = l.id ORDER BY l.title;').fetchall()
  • for todo in todos:
  • print(todo['title'], ':', todo['content'])

Trước tiên, bạn nhập get_db_connection từ file app.py sau đó mở một kết nối và thực hiện truy vấn ( lưu ý đây là cùng một truy vấn SQL mà bạn có trong file app.py của bạn ). Trong vòng lặp for bạn in tiêu đề của danh sách và nội dung của từng mục việc cần làm.

Đầu ra sẽ như sau:

Output
Home : Buy fruit Home : Cook dinner Study : Learn Flask Study : Learn SQLite Work : Morning meeting 

Đóng REPL bằng CTRL + D

Đến đây bạn đã hiểu cách các phép nối SQL hoạt động và những gì truy vấn đạt được, hãy quay trở lại hàm xem index() trong file app.py của bạn. Sau khi khai báo biến todos , bạn group các kết quả bằng đoạn mã sau:

lists = {}  for k, g in groupby(todos, key=lambda t: t['title']):     lists[k] = list(g) 

Trước tiên, bạn khai báo một từ điển trống được gọi là lists , sau đó sử dụng vòng lặp for để group các kết quả trong biến todos theo tiêu đề của danh sách. Bạn sử dụng hàm groupby() mà bạn đã nhập từ thư viện tiêu chuẩn itertools . Hàm này sẽ đi qua từng mục trong biến todos và tạo ra một group kết quả cho mỗi khóa trong vòng lặp for .

k đại diện cho danh hiệu danh sách ( nghĩa là , Home , Study , Work ), được extract bằng chức năng bạn vượt qua các key tham số của groupby() chức năng. Trong trường hợp này, hàm lambda t: t['title'] nhận một mục việc cần làm và trả về tiêu đề của danh sách (như bạn đã làm trước đây với todo['title'] trong vòng lặp for trước đó). g đại diện cho group chứa các mục việc cần làm của mỗi tiêu đề danh sách. Ví dụ: trong lần lặp đầu tiên, k sẽ là 'Home' , trong khi g là một lần lặp sẽ chứa các mục 'Buy fruit''Cook dinner' .

Điều này cung cấp cho ta sự thể hiện mối quan hệ một-nhiều giữa danh sách và mục, trong đó mỗi tiêu đề danh sách có một số mục việc cần làm.

Khi chạy file app.py và sau khi vòng lặp for kết thúc thực thi, lists sẽ như sau:

Output
{'Home': [<sqlite3.Row object at 0x7f9f58460950>,           <sqlite3.Row object at 0x7f9f58460c30>],  'Study': [<sqlite3.Row object at 0x7f9f58460b70>,            <sqlite3.Row object at 0x7f9f58460b50>],  'Work': [<sqlite3.Row object at 0x7f9f58460890>]} 

Mỗi đối tượng sqlite3.Row sẽ chứa dữ liệu bạn truy xuất từ bảng items bằng cách sử dụng truy vấn SQL trong hàm index() . Để trình bày dữ liệu này tốt hơn, ta hãy tạo một chương trình đi qua từ điển lists và hiển thị từng danh sách và các mục của nó.

Mở một file có tên list_example.py trong folder flask_todo của bạn:

  • nano list_example.py

Sau đó thêm mã sau:

flask_todo / list_example.py
 from itertools import groupby from app import get_db_connection  conn = get_db_connection() todos = conn.execute('SELECT i.content, l.title FROM items i JOIN lists l \                         ON i.list_id = l.id ORDER BY l.title;').fetchall()  lists = {}  for k, g in groupby(todos, key=lambda t: t['title']):     lists[k] = list(g)  for list_, items in lists.items():     print(list_)     for item in items:         print('    ', item['content']) 

Lưu và đóng file .

Điều này rất giống với nội dung trong hàm xem index() của bạn. Vòng lặp for cuối cùng ở đây minh họa cách cấu trúc từ điển lists . Đầu tiên, bạn lướt qua các mục của từ điển, in tiêu đề danh sách (nằm trong list_ ), sau đó xem qua từng group mục việc cần làm thuộc danh sách và in giá trị nội dung của mục đó.

Chạy chương trình list_example.py :

  • python list_example.py

Đây là kết quả của list_example.py :

Output
Home      Buy fruit      Cook dinner Study      Learn Flask      Learn SQLite Work      Morning meeting 

Đến đây bạn đã hiểu từng phần của hàm index() , hãy tạo một mẫu cơ sở và tạo index.html mà bạn đã hiển thị bằng cách sử dụng dòng return render_template('index.html', lists=lists) .

Trong folder flask_todo của bạn, hãy tạo một folder templates và mở một file có tên là base.html bên trong nó:

  • mkdir templates
  • nano templates/base.html

Thêm mã sau vào bên trong base.html , lưu ý bạn đang sử dụng Bootstrap tại đây. Nếu bạn không quen với các mẫu HTML trong Flask, hãy xem Bước 3 của Cách tạo ứng dụng web bằng Flask trong Python 3 :

flask_todo / templates / base.html
<!doctype html> <html lang="en">   <head>     <!-- Required meta tags -->     <meta charset="utf-8">     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">      <!-- Bootstrap CSS -->     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">      <title>{% block title %} {% endblock %}</title>   </head>   <body>     <nav class="navbar navbar-expand-md navbar-light bg-light">         <a class="navbar-brand" href="">FlaskTodo</a>         <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">             <span class="navbar-toggler-icon"></span>         </button>         <div class="collapse navbar-collapse" id="navbarNav">             <ul class="navbar-nav">             <li class="nav-item active">                 <a class="nav-link" href="#">About</a>             </li>             </ul>         </div>     </nav>     <div class="container">         {% block content %} {% endblock %}     </div>      <!-- Optional JavaScript -->     <!-- jQuery first, then Popper.js, then Bootstrap JS -->     <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>   </body> </html> 

Lưu và đóng file .

Hầu hết mã trong khối trước là HTML tiêu chuẩn và mã bắt buộc cho Bootstrap. Các <meta> cung cấp thông tin cho trình duyệt web, <link> liên kết các file Bootstrap CSS và các <script> là các liên kết đến mã JavaScript cho phép một số tính năng Bootstrap bổ sung. Kiểm tra tài liệu Bootstrap để biết thêm thông tin.

Tiếp theo, tạo index.html sẽ mở rộng file base.html này:

  • nano templates/index.html

Thêm mã sau vào index.html :

flask_todo / templates / index.html
{% extends 'base.html' %}  {% block content %}     <h1>{% block title %} Welcome to FlaskTodo {% endblock %}</h1>     {% for list, items in lists.items() %}         <div class="card" style="width: 18rem; margin-bottom: 50px;">             <div class="card-header">                 <h3></h3>             </div>             <ul class="list-group list-group-flush">                 {% for item in items %}                     <li class="list-group-item"></li>                 {% endfor %}             </ul>         </div>     {% endfor %} {% endblock %} 

Ở đây, bạn sử dụng vòng lặp for để đi qua từng mục của từ điển lists , bạn hiển thị tiêu đề danh sách dưới dạng tiêu đề thẻ bên trong <h3> , sau đó sử dụng group danh sách để hiển thị từng mục việc cần làm thuộc danh sách trong <li> . Điều này tuân theo các luật tương tự được giải thích trong chương trình list_example.py .

Đến đây bạn sẽ đặt các biến môi trường mà Flask cần và chạy ứng dụng bằng các lệnh sau:

  • export FLASK_APP=app
  • export FLASK_ENV=development
  • flask run

Khi server phát triển đang chạy, bạn có thể truy cập URL http://127.0.0.1:5000/ trong trình duyệt của bạn . Bạn sẽ thấy một trang web có “Chào mừng đến với FlaskTodo” và các mục trong danh sách của bạn.

Trang chủ

Đến đây bạn có thể gõ CTRL + C để dừng server phát triển của bạn .

Bạn đã tạo một ứng dụng Flask hiển thị danh sách việc cần làm và các mục của mỗi danh sách. Trong bước tiếp theo, bạn sẽ thêm một trang mới để tạo các mục việc cần làm mới.

Bước 3 - Thêm các việc cần làm mới

Trong bước này, bạn sẽ tạo một lộ trình mới để tạo các mục việc cần làm, bạn sẽ chèn dữ liệu vào các bảng database và liên kết các mục với danh sách mà chúng thuộc về.

Đầu tiên, hãy mở file app.py :

  • nano app.py

Sau đó, thêm một tuyến đường mới /create với một chức năng xem được gọi là create() ở cuối file :

flask_todo / app.py
... @app.route('/create/', methods=('GET', 'POST')) def create():     conn = get_db_connection()     lists = conn.execute('SELECT title FROM lists;').fetchall()      conn.close()     return render_template('create.html', lists=lists) 

Lưu và đóng file .

Vì bạn sẽ sử dụng tuyến đường này để chèn dữ liệu mới vào database thông qua biểu mẫu web, bạn cho phép cả yêu cầu GET và POST bằng cách sử dụng methods=('GET', 'POST') trong trình trang trí app.route() . Trong chức năng dạng xem create() , bạn mở một kết nối database , sau đó lấy tất cả các tiêu đề danh sách có sẵn trong database , đóng kết nối và hiển thị một mẫu create.html chuyển nó các tiêu đề danh sách.

Tiếp theo, mở file mẫu mới có tên là create.html :

  • nano templates/create.html

Thêm mã HTML sau vào create.html :

flask_todo / templates / create.html
{% extends 'base.html' %}  {% block content %} <h1>{% block title %} Create a New Item {% endblock %}</h1>  <form method="post">     <div class="form-group">         <label for="content">Content</label>         <input type="text" name="content"                placeholder="Todo content" class="form-control"                value=""></input>     </div>      <div class="form-group">         <label for="list">List</label>         <select class="form-control" name="list">             {% for list in lists %}                 {% if list['title'] == request.form['list'] %}                     <option value="" selected>                                              </option>                 {% else %}                     <option value="">                                              </option>                 {% endif %}             {% endfor %}         </select>     </div>     <div class="form-group">         <button type="submit" class="btn btn-primary">Submit</button>     </div> </form> {% endblock %} 

Lưu và đóng file .

Bạn sử dụng request.form để truy cập dữ liệu biểu mẫu được lưu trữ trong trường hợp có sự cố xảy ra với việc gửi biểu mẫu của bạn (ví dụ: nếu không có nội dung việc cần làm nào được cung cấp). Trong phần tử <select> , bạn lặp qua các danh sách mà bạn đã truy xuất từ database trong hàm create() . Nếu tiêu đề danh sách bằng với những gì được lưu trữ trong request.form thì tùy chọn đã chọn là tiêu đề danh sách đó, nếu không, bạn hiển thị tiêu đề danh sách trong <option> bình thường không được <option> .

Bây giờ, trong terminal, hãy chạy ứng dụng Flask của bạn:

  • flask run

Sau đó truy cập http://127.0.0.1:5000/create trong trình duyệt của bạn, bạn sẽ thấy biểu mẫu tạo mục việc cần làm mới, lưu ý biểu mẫu này chưa hoạt động vì bạn không có mã để xử lý các yêu cầu ĐĂNG được gửi bởi trình duyệt khi gửi biểu mẫu.

CTRL + C để dừng server phát triển của bạn.

Tiếp theo, hãy thêm mã để xử lý các yêu cầu POST vào hàm create() và làm cho biểu mẫu hoạt động bình thường, hãy mở app.py :

  • nano app.py

Sau đó, chỉnh sửa hàm create() để trông giống như sau:

flask_todo / app.py
... @app.route('/create/', methods=('GET', 'POST')) def create():     conn = get_db_connection()      if request.method == 'POST':         content = request.form['content']         list_title = request.form['list']          if not content:             flash('Content is required!')             return redirect(url_for('index'))          list_id = conn.execute('SELECT id FROM lists WHERE title = (?);',                                  (list_title,)).fetchone()['id']         conn.execute('INSERT INTO items (content, list_id) VALUES (?, ?)',                      (content, list_id))         conn.commit()         conn.close()         return redirect(url_for('index'))      lists = conn.execute('SELECT title FROM lists;').fetchall()      conn.close()     return render_template('create.html', lists=lists) 

Lưu và đóng file .

Bên trong điều kiện request.method == 'POST' bạn nhận được nội dung của mục việc cần làm và tiêu đề của danh sách từ dữ liệu biểu mẫu. Nếu không có nội dung nào được gửi, bạn gửi tin nhắn cho user bằng hàm flash() và chuyển hướng đến trang index . Nếu điều kiện này không được kích hoạt, thì bạn thực hiện SELECT để lấy ID danh sách từ tiêu đề danh sách được cung cấp và lưu nó trong một biến có tên list_id . Sau đó, bạn thực thi INSERT INTO để chèn mục việc cần làm mới vào bảng items . Bạn sử dụng biến list_id để liên kết mục với danh sách mà nó thuộc về. Cuối cùng, bạn thực hiện giao dịch, đóng kết nối và chuyển hướng đến trang index .

Bước cuối cùng, bạn sẽ thêm một liên kết đến /create trong thanh chuyển và hiển thị các thông báo nhấp nháy bên dưới nó, để thực hiện việc này, hãy mở base.html :

  • nano templates/base.html

Chỉnh sửa file bằng cách thêm một mục chuyển <li> mới liên kết đến chức năng chế độ xem create() . Sau đó, hiển thị các thông báo đã nhấp nháy bằng cách sử dụng vòng lặp for phía trên khối content . Chúng có sẵn trong hàm get_flashed_messages() Flask :

flask_todo / templates / base.html
<nav class="navbar navbar-expand-md navbar-light bg-light">     <a class="navbar-brand" href="">FlaskTodo</a>     <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">         <span class="navbar-toggler-icon"></span>     </button>     <div class="collapse navbar-collapse" id="navbarNav">         <ul class="navbar-nav">         <li class="nav-item active">             <a class="nav-link" href="">New</a>         </li>          <li class="nav-item active">             <a class="nav-link" href="#">About</a>         </li>         </ul>     </div> </nav> <div class="container">     {% for message in get_flashed_messages() %}         <div class="alert alert-danger"></div>     {% endfor %}     {% block content %} {% endblock %} </div> 

Lưu và đóng file .

Bây giờ, trong terminal, hãy chạy ứng dụng Flask của bạn:

  • flask run

Một liên kết đến /create mới sẽ xuất hiện trong thanh chuyển . Nếu bạn chuyển đến trang này và cố gắng thêm một mục việc cần làm mới mà không có nội dung, bạn sẽ nhận được một thông báo nhấp nháy cho biết Nội dung là bắt buộc! . Nếu bạn điền vào biểu mẫu nội dung, một mục việc cần làm mới sẽ xuất hiện trên trang index .

Trong bước này, bạn đã thêm khả năng tạo các mục việc cần làm mới và lưu chúng vào database .

Bạn có thể tìm thấy mã nguồn cho dự án này trong kho này .

Kết luận

Đến đây bạn có một ứng dụng để quản lý danh sách việc cần làm và các mục. Mỗi danh sách có một số mục việc cần làm và mỗi mục việc cần làm thuộc về một danh sách duy nhất trong mối quan hệ một-nhiều. Bạn đã học cách sử dụng Flask và SQLite để quản lý nhiều bảng database liên quan, cách sử dụng khóa ngoại và cách truy xuất và hiển thị dữ liệu liên quan từ hai bảng trong ứng dụng web bằng cách sử dụng các phép nối SQLite.

Hơn nữa, bạn đã group các kết quả bằng cách sử dụng hàm groupby() , chèn dữ liệu mới vào database và liên kết các hàng trong bảng database với các bảng mà chúng có liên quan. Bạn có thể tìm hiểu thêm về foreign keys và mối quan hệ database từ tài liệu SQLite .

Bạn cũng có thể đọc thêm nội dung Python Framework của ta . Nếu bạn muốn xem module sqlite3 Python, hãy đọc hướng dẫn của ta về Cách sử dụng module sqlite3 trong Python 3 .


Tags:

Các tin liên quan

Cách kết nối với dịch vụ database trên Ubuntu 18.04
2020-06-16
Cách tạo ứng dụng Django và kết nối nó với database
2020-05-07
Cách sử dụng Di chuyển database và Trình seeding để Thiết lập database Tóm tắt trong Laravel
2020-02-13
Cách tạo một ứng dụng lập hóa đơn đơn giản với node: database và API
2019-12-12
Cách cài đặt WordPress với dịch vụ database trên Ubuntu 18.04
2019-08-20
Dịch vụ Database online
2019-02-14
Tìm hiểu database phân đoạn - Database Sharding
2019-02-07
Cách thiết lập database từ xa để tối ưu hóa hiệu suất trang web với MySQL trên Ubuntu 18.04
2018-11-28
Cách quản lý database SQL
2018-09-26
Cách cải thiện tìm kiếm database với tìm kiếm toàn văn bản (Full Text Search) trong MySQL 5.6 trên Ubuntu 16.04
2017-10-30