Flask 应用部署文档(示例)

1. 环境准备

1.1 更新系统包并安装必要的软件:

sudo apt update
sudo apt install python3 python3-pip python3-venv sqlite3 -y

1.2 创建项目目录:

mkdir book_library
cd book_library

1.3 创建并激活虚拟环境:

python3 -m venv venv
source venv/bin/activate

1.4 在虚拟环境中安装 Flask:

pip install flask

2. 项目结构设置

2.1 创建必要的目录和文件:

mkdir templates static
mkdir static/css static/js
touch app.py database.py
touch templates/index.html templates/book.html
touch static/css/style.css static/js/main.js

3. 数据库设置

3.1 创建并初始化 SQLite 数据库:

sqlite3 books.db
CREATE TABLE books (id INTEGER PRIMARY KEY, title TEXT, content TEXT);
CREATE VIRTUAL TABLE books_fts USING fts5(title, content);
INSERT INTO books (title, content) VALUES ('Sample Book', 'This is a sample book content.');
INSERT INTO books_fts (title, content) SELECT title, content FROM books;
.quit

4. 应用代码

4.1 编辑 app.py

from flask import Flask, render_template, jsonify, request
import sqlite3

app = Flask(__name__)

def get_db_connection():
  conn = sqlite3.connect('books.db')
  conn.row_factory = sqlite3.Row
  return conn

@app.route('/')
def index():
  conn = get_db_connection()
  books = conn.execute('SELECT * FROM books').fetchall()
  conn.close()
  return render_template('index.html', books=books)

@app.route('/book/<int:book_id>')
def book(book_id):
  conn = get_db_connection()
  book = conn.execute('SELECT * FROM books WHERE id = ?', (book_id,)).fetchone()
  conn.close()
  if book is None:
      return "Book not found", 404
  return render_template('book.html', book=book)

@app.route('/search')
def search():
  query = request.args.get('q', '')
  conn = get_db_connection()
  results = conn.execute('SELECT * FROM books_fts WHERE books_fts MATCH ? ORDER BY rank', (query,)).fetchall()
  conn.close()
  return jsonify([dict(row) for row in results])

if __name__ == '__main__':
  app.run(debug=True, host='0.0.0.0', port=5000)

5. HTML 模板

5.1 编辑 templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Book Library</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>Book Library</h1>
    <input type="text" id="search" placeholder="Search books...">
    <ul id="results"></ul>
    <h2>All Books:</h2>
    <ul>
    {% for book in books %}
        <li><a href="{{ url_for('book', book_id=book['id']) }}">{{ book['title'] }}</a></li>
    {% endfor %}
    </ul>
    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>

5.2 编辑 templates/book.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ book['title'] }}</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>{{ book['title'] }}</h1>
    <p>{{ book['content'] }}</p>
    <a href="{{ url_for('index') }}">Back to all books</a>
</body>
</html>

6. 静态文件

6.1 编辑 static/css/style.css

body {
    font-family: Arial, sans-serif;
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
}

ul {
    list-style-type: none;
    padding: 0;
}

li {
    margin-bottom: 10px;
}

input[type="text"] {
    width: 100%;
    padding: 10px;
    margin-bottom: 20px;
}

6.2 编辑 static/js/main.js

document.addEventListener('DOMContentLoaded', function() {
    const searchInput = document.getElementById('search');
    const resultsContainer = document.getElementById('results');

    searchInput.addEventListener('input', function() {
        if (this.value.length > 2) {
            fetch('/search?q=' + this.value)
                .then(response => response.json())
                .then(data => {
                    resultsContainer.innerHTML = '';
                    data.forEach(book => {
                        const li = document.createElement('li');
                        li.innerHTML = `<a href="/book/${book.id}">${book.title}</a>`;
                        resultsContainer.appendChild(li);
                    });
                });
        } else {
            resultsContainer.innerHTML = '';
        }
    });
});

7. 运行应用

在项目目录中,确保虚拟环境已激活,然后运行:

python app.py

现在,测试通过 http://192.168.1.100:5000 访问应用。

8.退出虚拟环境:

在当前虚拟环境下比如(venv) root@testserver:/# 执行下面的命令

deactivate