Python后端开发之旅(一)——连接数据库

常见的语法糖

常用的内置对象

在这里插入图片描述

python 没有 double 类型
Python 中使用的浮点数类型是 float ,它代表双精度浮点数,具有双精度的浮点数精度

在这里插入图片描述

range、map、zip、filter、enumerate等迭代器对象是Python 中比较常用的内置对象,支持某些与容器类对象类似的用法,统称为可迭代对象
在这里插入图片描述

重要对象 (除了reduce是函数())

一定会 包含索引的,就是index,从0开始计数
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

元组 和 列表的异同

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

类型转化

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

排序和逆序

在这里插入图片描述

在这里插入图片描述

生成器对象

生成器表达式

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

生成器函数

在这里插入图片描述

yield 是 Python 中的一个关键字,用于定义一个生成器函数(generator function)

它和 return 类似,但有一个关键区别:

  • return 返回值后函数结束
  • yield 返回值后,函数暂停并记住当前位置下次调用时从这里继续
💡 基本语法
def my_generator():
    yield 1
    yield 2
    yield 3

使用方式:

gen = my_generator()
print(next(gen))  # 输出: 1
print(next(gen))  # 输出: 2
print(next(gen))  # 输出: 3
# print(next(gen)) # StopIteration 错误

⚠️ 每次 next() 调用会执行到下一个 yield,然后暂停。


🌟 实际应用场景:处理大数据流
def count_up_to(n):
    for i in range(n):
        yield i

# 只有需要时才计算
for num in count_up_to(5):
    print(num)  # 输出: 0, 1, 2, 3, 4

✅ 优点:节省内存!不需要一次性生成整个列表。

对比传统方式:

# ❌ 内存占用高 (O(n))
def count_up_to_list(n):
    return list(range(n))

nums = count_up_to_list(1000000)
# ✅ 内存高效 (O(1))
for num in count_up_to(1000000):
    pass  # 每次只生成一个数

✅ 生成器(Generator)和迭代器(Iterator)是什么?

📌 迭代器(Iterator)定义:
  • 可以被 next() 调用的对象
  • 实现了 __iter__()__next__() 方法
  • 一次产生一个值,直到耗尽
my_list = [1, 2, 3]
iterator = iter(my_list)  # 转换为迭代器

print(next(iterator))  # 1
print(next(iterator))  # 2
print(next(iterator))  # 3
# print(next(iterator)) # StopIteration

所有可迭代对象(如 list, tuple, str)都可以通过 iter() 转为迭代器


📌 生成器(Generator) 定义:
  • 使用 yield 的函数 → 生成器函数
  • 用于处理大数据流,调用它不会立即执行,而是返回一个生成器对象
  • 懒惰求值(Lazy Evaluation)
  • 只在需要时生成数据
  • 极致节省内存
def gen():
    yield 1
    yield 2
    yield 3

g = gen()  # g 是生成器对象
print(type(g))  # <class 'generator'>

types.GeneratorType 是什么?

types.GeneratorType 是 Python 标准库中 types 模块定义的一个 类型对象,用来表示“生成器”的类型

import types

def my_gen():
    yield 1

g = my_gen()

print(type(g))              # <class 'generator'>
print(isinstance(g, types.GeneratorType))  # True
print(isinstance(g, int))   # False
🛠️ 其他相关类型(Python 3.x)
类型 描述
types.GeneratorType 生成器的类型
types.CoroutineType 协程的类型(async/await)
types.FunctionType 普通函数的类型
types.MethodType 方法的类型
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib = fibonacci()

# 生成器对象
print(type(fib))           # <class 'generator'>
print(isinstance(fib, types.GeneratorType))  # True
print(isinstance(fib, abc.Iterator))         # True,生成器属于迭代器

# 使用
print(next(fib))  # 0
print(next(fib))  # 1
print(next(fib))  # 1
print(next(fib))  # 2
  1. 内存优化:处理大文件、流数据、无限序列
  2. 代码简洁yield 替代复杂的循环
  3. 延迟计算:只在需要时才生成数据

在这里插入图片描述

流程控制—— break、continue、pass 的區別

完整链接🔗

  • break:強制跳出 ❮整個❯ 迴圈

  • continue:強制跳出 ❮本次❯ 迴圈,繼續進入下一圈

  • pass:不做任何事情,所有的程式都將繼續

    • pass 就像是 To do 的概念,在寫程式的時候,有時候想的比實際寫出來的速度快,但還沒有實作出來,空著內容不寫又會產生語法錯誤🤦‍♂️
    • 這時就會使用 pass 來替代,當作是個指標,提醒自己之後要來完成

装饰器

不改变函数自身代码的情况下,动态地增加功能

看ku

def decorator(func):
    def wrapper(*args, **kwargs): # 都会定义这个 方法
        # 在函数调用之前执行的代码
        result = func(*args, **kwargs)
        # 在函数调用之后执行的代码
        return result
    return wrapper

🌟 什么是 with 语句?

with 是 Python 中一个非常优雅且安全的上下文管理器(Context Manager),主要用于自动处理资源的“打开”和“关闭”,比如文件、数据库连接、锁等。

它的核心思想是:

“进入时做点事,退出时自动清理。”

这样能避免忘记手动关闭资源,防止内存泄漏或文件损坏等问题。


🔧 基本语法:

with 表达式 as 变量:
    # 执行代码块
  • 表达式必须返回一个支持上下文管理器的对象(如文件对象)
  • as 变量:可选,用于接收表达式的结果(比如文件对象)

✅ 示例 1:操作文件

# 不推荐的方式(容易忘记关闭)
file = open('test.txt', 'w')
file.write('Hello, World!')
file.close()

# 推荐的方式:使用 with
with open('test.txt', 'w') as f:
    f.write('Hello, World!')
    # 自动关闭文件,不需要写 close()

✅ 优点:

  • 文件会自动关闭,即使代码出错(如异常抛出)
  • 更简洁、更安全

✅ 示例 2:使用数据库连接

import sqlite3

with sqlite3.connect('example.db') as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")
    results = cursor.fetchall()
    # 连接会自动关闭,无需手动 commit 或 close

✅ 示例 3:使用线程锁(threading.Lock)

import threading

lock = threading.Lock()

with lock:
    # 任何需要加锁的代码放这里
    print("临界区")
    # lock 自动释放,即使发生异常

📦 with 的工作原理(底层机制)

with 背后依赖两个方法:

  • __enter__(): 进入 with 块时调用 → 通常是“打开资源”
  • __exit__(): 离开 with 块时调用(无论是否出错)→ 通常是“关闭资源”

这些方法由上下文管理器对象提供(如文件、数据库连接、锁等)。


✅ 自定义上下文管理器(进阶)

你可以用类来定义自己的 with 语句:

class MyContext:
    def __enter__(self):
        print("进入上下文")
        return self  # 可以返回任意值

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("离开上下文")
        # 如果发生异常,exc_type 不为 None
        # 返回 False 表示继续抛出异常;True 表示忽略异常
        return False

# 使用
with MyContext() as ctx:
    print("在上下文中执行")

内部类和函数

嵌套函数(nested function)或内部函数(inner function)

  • 可以在一个函数内部定义另一个函数,这种做法称为嵌套函数(nested function)或内部函数(inner function
  • 嵌套函数可以帮助将某些功能逻辑封装在一个局部范围内,使得这些逻辑对外部不可见,仅在父函数的上下文中使用。这种做法有助于减少全局命名空间的污染,避免命名冲突
  • 内部函数可以访问外部函数的局部变量和参数
  • 在外部函数 之外 无法调用到 内部函数,只有在外部函数 内才可以调用到
  • 注意仍然 定义在调用之前

嵌套类 或 内部类

  • 为什么会使用呢?
  • 把两个或者多个类打包在一起。假设你有两个类Car和Engine。每一个Car都需要一个Engine,但是每一个Engine不会在没有Car的时候被使用。因此我们可以让Engine成为Car的内部类。这有助于我们保存代码
  • 可以使用self关键词来访问内部类
  • 内部类不能直接用外部类的属性和方法,还得加上类名

日志框架

一份 Python logging 配置有下面四个部分组成:

  • Loggers
  • Handlers
  • 过滤器Filter
  • Formatters
    流程:创建logging.getLogger-创建:logging.handler–handler.setLevel–logging.Formatter/handler.setFormatter–logger.addHandler

按日回滚

info_handler = logging.handlers.TimedRotatingFileHandler(log_path + ".log",
                                                        when="D",
                                                        backupCount=7)

每天午夜时分,日志系统会自动:

  • ✅ 重命名当前 liantiao_ai.log → liantiao_ai.log.2025-12-20
  • ✅ 创建新的空文件 liantiao_ai.log
  • ✅ 删除超过7天的旧日志文件

在这里插入图片描述

Filter

在日志记录从 logger 传到 handler 的过程中,使用 Filter 来做额外的控制。

默认情况下,只要级别匹配,任何日志消息都会被处理。不过,也可以通过添加 filter 来给日志处理的过程增加额外条件,例如,可以添加一个 filter 只允许某个特定来源的 ERROR 消息输出。

Filter 还被用来在日志输出之前对日志记录做修改。例如,可以写一个 filter,当满足一定条件时,把日志记录从 ERROR 降到 WARNING 级别。

Filter 在 logger 和 handler 中都可以添加;多个 filter 可以链接起来使用,来做多重过滤操作。

为 logger 命名

对 logging.getLogger() 的调用会获取(必要时会创建)一个 logger 的实例。不同的 logger 实例用名字来区分。这个名字是为了在配置的时候指定 logger。

按照惯例,logger 的名字通常是包含该 logger 的 Python 模块名,即 __name__。这样可以基于模块来过滤和处理日志请求。不过,如果你有其他的方式来组织你的日志消息,可以为 logger 提供点号分割的名字来标识它:

# Get an instance of a specific named logger
logger = logging.getLogger('project.interesting.stuff')

这种 logger 的名字,用点号分隔的路径定义了一种层次结构。project.interesting 这个 logger 是 project.interesting.stuff logger 的上级;而 project logger 是 project.interesting logger 的上级。

为什么这种层级结构是重要的呢?因为 logger 可以设置为将日志的请求传播给上级。这样就可以在 logger 树结构的顶层定义一组单独的 handler,来捕获所有下层的日志请求。
在 project 命名空间中定义的 logger handler 将会捕获 project.interesting 和 project.interesting.stuff 这两个 logger 中的所有日志请求。

可以基于 logger 来控制传播的行为。 如果你不希望某个 logger 传播给上级,可以关闭它,比如:

def configure_sqlalchemy_logging():
    """ 控制sqlalchemy日志输出 """
    sa_logger = logging.getLogger('sqlalchemy.engine')
    sa_logger.setLevel(logging.WARNING)  # 控制 SQLAlchemy 输出级别
    sa_logger.handlers.clear()  # 避免重复输出
    sa_logger.propagate = False  # 防止冒泡到 root logger
  • ✅ 不输出任何日志(因为清空了所有处理器)
  • ✅ 不传播到根日志器(不会出现在控制台或其他地方)

示例:同时输出到控制台和文件

import logging

# 创建logger
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG)

# 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 文件处理器  
file_handler = logging.FileHandler('debug.log')
file_handler.setLevel(logging.DEBUG)

# 添加处理器到logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# 使用
logger.debug('调试信息')    # 只写入文件
logger.info('普通信息')     # 输出到控制台+文件
logger.error('错误信息')    # 输出到控制台+文件

函数参数解包(Unpacking)机制

✅ 定义:
“解包”是指把一个集合类对象(如元组、列表、字典)中的元素拆分成多个独立值,或者反过来,把多个值打包成一个集合。

它本质上是“展开”或“收集”的过程。

✅ 举个例子理解

# 解包:把列表的元素拆开
a, b, c = [1, 2, 3]
print(a)  # 输出 1

这里就是“解包”—— 把 [1,2,3] 解包成三个变量。

对应地,也有“打包”:

# 打包:把多个值合并为一个元组
x = 1, 2, 3
print(x)  # (1, 2, 3)

1️⃣ *args 是什么?怎么用?

✅ 定义:
*args 是一个可变位置参数(positional arguments),用于接收任意数量的位置参数,并将其打包成一个 元组

“args” 是任意命名(比如 *nums 也行),但习惯叫 *args

✅ 示例

def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3))      # 6
print(sum_all(10, 20))       # 30
print(sum_all())             # 0 (空元组)

📌 关键点:

  • *args 接收的是位置参数
  • 参数会被自动打包成一个 元组(tuple)

✅ 更灵活的使用方式

def greet(name, *messages):
    print(f"Hello {name}!")
    for msg in messages:
        print(msg)

greet("Alice", "How are you?", "Nice to meet you!") 
# 输出:
# Hello Alice!
# How are you?
# Nice to meet you!

2️⃣ **kwargs 是什么?怎么用?

✅ 定义:
**kwargs 是一个可变关键字参数(keyword arguments),用于接收任意数量的关键字参数,并将其打包成一个 字典

“kwargs” 是 “keyword arguments” 的缩写(也可以叫 **other

✅ 示例

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Bob", age=25, city="Beijing")
# 输出:
# name: Bob
# age: 25
# city: Beijing

📌 关键点:

  • **kwargs 接收的是带名字的参数(如 name="Alice"
  • 被打包成一个字典(dict)

✅ 结合 *args**kwargs

def func(*args, **kwargs):
    print("Positional args:", args)
    print("Keyword args:", kwargs)

func(1, 2, 3, name="Alice", age=30)
# 输出:
# Positional args: (1, 2, 3)
# Keyword args: {'name': 'Alice', 'age': 30}

3️⃣ 其他形式的“解包”语法

除了函数参数里的 *args**kwargs作为打包,Python 还支持在赋值调用进行解包


✅ 1. 函数调用时的解包(星号解包)

🟢 *:解包可迭代对象(如列表、元组)作为位置参数

def add(a, b, c):
    return a + b + c

nums = [1, 2, 3]
result = add(*nums)   # 相当于 add(1, 2, 3)
print(result)         # 6

🟢 **:解包字典作为关键字参数

def greet(name, age):
    print(f"{name} is {age} years old")

info = {"name": "Alice", "age": 25}
greet(**info)         # 相当于 greet(name="Alice", age=25)

✅ 2. 赋值时的解包(增强版 unpacking)

🟢 解包列表/元组到多个变量

a, b, c = [1, 2, 3]
print(a, b, c)  # 1 2 3

# 可以用 * 收集剩余部分
first, *rest = [1, 2, 3, 4, 5]
print(first)     # 1
print(rest)      # [2, 3, 4, 5]

🟢 在循环中解包

pairs = [(1, "a"), (2, "b"), (3, "c")]
for num, letter in pairs:
    print(num, letter)

✅ 3. 字典解包(**

data = {"name": "Alice", "age": 25}
new_data = {"city": "Beijing", **data}
print(new_data)  # {'city': 'Beijing', 'name': 'Alice', 'age': 25}

👉 就像“拼接”两个字典,用 ** 解包原字典


✅ 4. *** 在函数定义中的作用总结

符号 用途 说明
*args 接收任意位置参数 包装成元组
**kwargs 接收任意关键字参数 包装成字典
* 解包列表/元组 传递为多个位置参数
** 解包字典 传递为多个关键字参数

4️⃣ 终极总结图

           ┌───────────────┐
           │   解包 (Unpack) │
           └───────────────┘
                    ▲
            ┌─────────────┐
            │    打包 (Pack)│
            └─────────────┘

          ↓                            ↑
┌─────────────────┐      ┌─────────────────┐
│ *args    →  tuple │      │ list/tuple → *    │
└─────────────────┘      └─────────────────┘
          ↓                            ↑
┌─────────────────┐      ┌─────────────────┐
│ **kwargs → dict  │      │ dict → **        │
└─────────────────┘      └─────────────────┘

魔法方法

魔法方法(内置方法)合集的基本使用以及原理

is 和 == 的区别

  • is 表示的是对象标示符(object identity),而 == 表示的是相等(equality)
  • is 的作用是用来检查对象的标示符是否一致,也就是比较两个对象在内存中的地址是否一样
    • 我们在检查 a is b 的时候,其实相当于检查 id(a) == id(b)
  • == 是用来检查两个对象是否相等
    • 检查 a == b 的时候,实际是调用了对象 a 的 eq() 方法,a == b 相当于 a.__eq__(b)
    • java 的是相反的,java中==是判断内存当中的地址的,但是pyhton中的是判断内容了,is才是判断地址了
  • 一般情况下,如果 a is b 返回True的话,即 a 和 b 指向同一块内存地址的话,a == b 也返回True,即 a 和 b 的值也相等

连接数据库

🔹 一、Python 连接数据库的通用流程

  1. 安装数据库驱动(Driver)
  2. 创建连接对象(Connection)
  3. 创建游标对象(Cursor)
  4. 执行 SQL 语句(查询/插入/更新等
  5. 提交事务(如果需要)
  6. 关闭连接

✅ 案例 1:使用 sqlite3小型内置模块,无需安装

SQLite 是轻量级数据库,适合学习和小型项目。

📦 步骤 1:导入模块

import sqlite3

📦 步骤 2:建立连接(会自动创建文件)

# 连接到 SQLite 数据库(如果不存在则创建)
conn = sqlite3.connect('example.db')

📦 步骤 3:创建游标

cursor = conn.cursor()

📦 步骤 4:执行 SQL(建表)

cursor.execute('''
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        age INTEGER
    )
''')

📦 步骤 5:插入数据

cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 25))
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 30))

使用 ? 占位符防止 SQL 注入!

📦 步骤 6:提交事务

conn.commit()

📦 步骤 7:查询数据

cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()

for row in rows:
    print(row)

📁 最终输出:

(1, 'Alice', 25)
(2, 'Bob', 30)

📦 步骤 8:关闭连接

cursor.close()
conn.close()

✅ 案例 2:连接 MySQL(需要安装驱动)

MySQL 更适合生产环境。

📦 步骤 1:安装驱动

pip install mysql-connector-python   # 或者 PyMySQL

推荐:mysql-connector-python 是官方驱动
替代:PyMySQL 更轻量,兼容性好


📦 步骤 2:连接 MySQL

import mysql.connector

# 连接参数(根据你的 MySQL 配置修改)
config = {
    'host': 'localhost',
    'user': 'root',
    'password': 'your_password',
    'database': 'test_db'
}

try:
    conn = mysql.connector.connect(**config)
    cursor = conn.cursor()

    # 创建表
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS employees (
            id INT AUTO_INCREMENT PRIMARY KEY,
            name VARCHAR(50),
            salary INT
        )
    ''')

    # 插入数据
    cursor.execute("INSERT INTO employees (name, salary) VALUES (%s, %s)", ('John', 5000))
    cursor.execute("INSERT INTO employees (name, salary) VALUES (%s, %s)", ('Jane', 6000))

    # 提交
    conn.commit()

    # 查询
    cursor.execute("SELECT * FROM employees")
    rows = cursor.fetchall()
    for row in rows:
        print(row)

except mysql.connector.Error as err:
    print(f"Error: {err}")
finally:
    if conn.is_connected():
        cursor.close()
        conn.close()

✅ 注意事项(MySQL)

  • 确保 MySQL 服务正在运行
  • 账号有权限访问数据库
  • 如果没安装 mysql-connector-python,请先安装
  • 使用 %s 占位符防注入

✅ 案例 3:使用 PyMySQL(替代方案)

pip install PyMySQL
import pymysql

conn = pymysql.connect(
    host='localhost',
    user='root',
    password='your_password',
    database='test_db',
    charset='utf8mb4'
)

cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS products (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), price FLOAT)")
cursor.execute("INSERT INTO products (name, price) VALUES (%s, %s)", ('Laptop', 999.99))
conn.commit()

cursor.execute("SELECT * FROM products")
print(cursor.fetchall())

cursor.close()
conn.close()

✅ 案例 4:连接 PostgreSQL(使用 psycopg2

pip install psycopg2-binary
import psycopg2

conn = psycopg2.connect(
    host="localhost",
    database="mydb",
    user="postgres",
    password="password"
)

cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS books (id SERIAL PRIMARY KEY, title VARCHAR(100))")
cursor.execute("INSERT INTO books (title) VALUES (%s)", ['The Great Gatsby'])
conn.commit()

cursor.execute("SELECT * FROM books")
print(cursor.fetchall())

cursor.close()
conn.close()

✅ 案例 5:连接 MongoDB(使用 pymongo

MongoDB 是 NoSQL 数据库,适合 JSON 格式存储。

pip install pymongo
from pymongo import MongoClient

# 连接本地 MongoDB
client = MongoClient('mongodb://localhost:27017/')
db = client['testdb']
collection = db['users']

# 插入文档
user = {"name": "Charlie", "age": 28}
collection.insert_one(user)

# 查询
result = collection.find_one({"name": "Charlie"})
print(result)

🔹 二、重要概念总结

技术 类型 特点
sqlite3 内置 不用安装,适合学习和小项目
mysql-connector-python 官方驱动 功能完整,稳定
PyMySQL 第三方 轻量,纯 Python 实现
psycopg2 PostgreSQL 最佳选择
pymongo MongoDB 支持文档型数据库

🔹 三、最佳实践建议

  1. 使用 参数化查询?%s)防止 SQL 注入
  2. ✅ 始终使用 try-except-finally 捕获错误并关闭连接
  3. ✅ 使用 上下文管理器 自动关闭连接(推荐!)
import sqlite3

with sqlite3.connect('example.db') as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")
    rows = cursor.fetchall()
    # 自动提交和关闭

🔹 四、进阶技巧

✅ 1. 使用 ORM(对象关系映射)

比如 SQLAlchemyDjango ORM,可以更方便地操作数据库。

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

engine = create_engine('sqlite:///example.db')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

# 添加用户
user = User(name='Alice')
session.add(user)
session.commit()

# 查询
users = session.query(User).all()

🔹 五、常见错误 & 解决方案

错误 原因 解决方法
ModuleNotFoundError: No module named 'mysql.connector' 没安装驱动 pip install mysql-connector-python
OperationalError: (2003, "Can't connect to MySQL server") 主机或端口错 检查 host, port, user, pwd
ProgrammingError: You have an error in your SQL syntax SQL 语法错误 检查引号、括号、字段名
TypeError: can't concat str to bytes 编码问题 charset='utf8mb4'(MySQL)

可视化插件——❤️

搜索 Database Clinent 然后直接下载即可

Web 应用开发入门对比——Flask & Django

Flask —— 轻量、灵活、适合初学者和小型项目
Django —— 全功能、大而全、适合中大型项目


🔹 一、Python Web 开发基本流程(通用)

  1. 安装 Python 和虚拟环境
  2. 安装 Web 框架(Flask 或 Django)
  3. 创建项目结构
  4. 编写视图函数(View)或路由(Route)
  5. 设计模板(HTML)或返回 JSON
  6. 启动服务器,测试访问

✅ 案例 1:用 Flask 开发一个简单的 Web 应用

📦 步骤 1:安装 Flask

pip install flask

📦 步骤 2:创建一个文件 app.py

from flask import Flask, render_template, request

# 创建 Flask 应用实例
app = Flask(__name__)

# 路由:访问根路径 / 显示欢迎页面
@app.route('/')
def home():
    return "<h1>Hello from Flask!</h1>"

# 路由:显示一个 HTML 页面
@app.route('/hello/<name>')
def greet(name):
    return f"<h1>Hello, {name}!</h1>"

# 路由:处理表单提交
@app.route('/form', methods=['GET', 'POST'])
def form():
    if request.method == 'POST':
        name = request.form['name']
        return f"Hello, {name}! Your form was submitted."
    return '''
        <form method="post">
            Name: <input type="text" name="name"><br>
            <input type="submit" value="Submit">
        </form>
    '''

# 路由:渲染 HTML 模板
@app.route('/template')
def show_template():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

📦 步骤 3:创建模板目录 templates/,并添加 index.html

project/
├── app.py
└── templates/
    └── index.html
<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Flask Template</title>
</head>
<body>
    <h1>Welcome to Flask!</h1>
    <p>This is a dynamic page.</p>
</body>
</html>

📦 步骤 4:运行应用

python app.py

访问:

  • http://localhost:5000/
  • http://localhost:5000/hello/Alice
  • http://localhost:5000/form

✅ 案例 2:用 Django 开发一个简单的 Web 应用

📦 步骤 1:安装 Django

pip install django

📦 步骤 2:创建项目(注意不是应用)

django-admin startproject myproject
cd myproject

这会生成结构:

myproject/
├── manage.py
└── myproject/
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

📦 步骤 3:创建第一个应用

python manage.py startapp myapp

更新 myproject/settings.py,加入应用:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',  # 添加你的应用
]

📦 步骤 4:创建视图(View)

编辑 myapp/views.py

from django.shortcuts import render
from django.http import HttpResponse

def home(request):
    return HttpResponse("<h1>Hello from Django!</h1>")

def greet(request, name):
    return HttpResponse(f"<h1>Hello, {name}!</h1>")

def form(request):
    if request.method == 'POST':
        name = request.POST['name']
        return HttpResponse(f"Hello, {name}! Form submitted.")
    return """
        <form method="post">
            Name: <input type="text" name="name"><br>
            <input type="submit" value="Submit">
        </form>
    """

📦 步骤 5:配置 URL 路由

编辑 myapp/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('hello/<str:name>/', views.greet, name='greet'),
    path('form/', views.form, name='form'),
]

然后在 myproject/urls.py 中包含它:项目中包含应用

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),  # 包含 myapp 的路由
]

📦 步骤 6:创建模板目录(可选)

创建 myapp/templates/,然后在 myproject/settings.py 中设置模板路径:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'myapp/templates'],  # 添加模板路径
        'APP_DIRS': True,
        ...
    },
]

创建 myapp/templates/index.html

<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Django Template</title>
</head>
<body>
    <h1>Welcome to Django!</h1>
</body>
</html>

📦 步骤 7:运行开发服务器

python manage.py runserver

访问:

  • http://localhost:8000/
  • http://localhost:8000/hello/Alice/
  • http://localhost:8000/form/

🔍 对比 Flask vs Django

特性 Flask Django
类型 微框架(Micro Framework) 全栈框架(Full Stack)
灵活性 高,自由度强 低,有固定结构
学习曲线 简单,适合新手 较陡,但功能强大
内建功能 基本路由 + 模板 ORM、Admin、Auth、Session、CSRF 等
是否需要额外库 是(需手动添加) 否(自带)
适合场景 小型 API、工具类服务 大型网站、博客、电商等

🔧 常见扩展技巧

✅ 1. 返回 JSON(前后端分离必备)

Flask 示例:
from flask import jsonify

@app.route('/api/users')
def api_users():
    users = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
    return jsonify(users)
Django 示例:
from django.http import JsonResponse

def api_users(request):
    users = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
    return JsonResponse(users, safe=False)

✅ 2. 使用数据库(以 SQLite 为例)

Flask + SQLAlchemy
pip install flask-sqlalchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)

# 创建表
with app.app_context():
    db.create_all()
Django 自带 ORM
# myapp/models.py
from django.db import models

class User(models.Model):
    name = models.CharField(max_length=50)

然后执行迁移:

python manage.py makemigrations
python manage.py migrate

✅ 3. 动态模板展示数据

Flask 示例:
@app.route('/users')
def users():
    users = ['Alice', 'Bob', 'Charlie']
    return render_template('users.html', users=users)

模板 users.html

<h1>Users</h1>
<ul>
{% for user in users %}
    <li>{{ user }}</li>
{% endfor %}
</ul>
Django 示例类似(使用 {{ }}{% %}

🎯 总结 & 建议

在这里插入图片描述

目标 推荐工具
快速学 Web 开发 ✅ Flask
构建复杂网站 ✅ Django
开发 REST API ✅ Flask + Marshmallow / Django REST Framework
数据分析 + Web 展示 ✅ Flask + Plotly / Dash

💡 一句话口诀记忆

  • Flask:轻巧灵活,像“乐高积木”一样拼接功能
  • Django:功能齐全,像“一体化厨房”直接开火做饭
  • Web 开发三步走:路由 → 视图 → 模板/JSON
  • 安全第一:防止 SQL 注入、XSS、CSRF

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐