30天学会Python编程:20. Python Web开发简介
20.1 Web基础概念
20.1.1 HTTP协议
20.1.2 请求/响应周期
- 客户端发送HTTP请求
- 服务器解析请求
- 应用处理业务逻辑
- 生成HTTP响应
- 返回给客户端
20.2 WSGI规范
20.2.1 WSGI接口
def simple_app(environ, start_response):
"""最简单的WSGI应用"""
status = '200 OK'
headers = [('Content-type', 'text/plain')]
start_response(status, headers)
return [b"Hello World!"]
# 使用wsgiref运行
from wsgiref.simple_server import make_server
httpd = make_server('', 8000, simple_app)
httpd.serve_forever()
20.2.2 中间件示例
class Middleware:
"""WSGI中间件示例"""
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
# 预处理
print("请求进入:", environ['PATH_INFO'])
# 调用下层应用
def custom_start_response(status, headers):
# 后处理
headers.append(('X-Middleware', 'Processed'))
return start_response(status, headers)
return self.app(environ, custom_start_response)
# 包装应用
wrapped_app = Middleware(simple_app)
20.3 Flask框架
20.3.1 基本应用
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return "<h1>Welcome</h1>"
@app.route('/api/data', methods=['GET', 'POST'])
def handle_data():
if request.method == 'POST':
return jsonify({"status": "received", "data": request.json})
return jsonify({"values": [1,2,3]})
if __name__ == '__main__':
app.run(debug=True)
20.3.2 模板渲染
from flask import render_template
@app.route('/user/<username>')
def show_profile(username):
# templates/user_profile.html
return render_template('user_profile.html',
username=username,
join_date='2023-01-01')
20.4 Django框架
20.4.1 MTV架构
20.4.2 快速开始
# views.py
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
return HttpResponse("Hello Django")
def user_view(request, username):
return render(request, 'user.html',
{'name': username})
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('user/<str:username>/', views.user_view)
]
20.5 异步Web框架
20.5.1 FastAPI示例
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.get("/")
async def root():
return {"message": "Hello FastAPI"}
@app.post("/items/")
async def create_item(item: Item):
return {"item": item.dict()}
# 运行: uvicorn main:app --reload
20.5.2 WebSocket支持
from fastapi import WebSocket
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Echo: {data}")
20.6 模板引擎
20.6.1 Jinja2语法
<!-- base.html -->
<html>
<head><title>{% block title %}{% endblock %}</title></head>
<body>
{% block content %}{% endblock %}
</body>
</html>
<!-- user.html -->
{% extends "base.html" %}
{% block title %}User {{ name }}{% endblock %}
{% block content %}
<h1>Welcome, {{ name }}!</h1>
{% if is_admin %}
<p>You have admin privileges</p>
{% endif %}
{% endblock %}
20.6.2 模板继承
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template('user.html')
output = template.render(name='Alice', is_admin=True)
print(output)
20.7 应用举例
案例1:博客
# Flask博客应用
from flask import Flask, render_template, request, redirect, url_for
from werkzeug.utils import secure_filename
import os
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'static/uploads'
# 模拟数据库
posts = [
{'id': 1, 'title': 'First Post', 'content': 'Hello World!'},
{'id': 2, 'title': 'Flask教程', 'content': '学习Flask Web开发'}
]
@app.route('/')
def index():
return render_template('index.html', posts=posts)
@app.route('/post/<int:post_id>')
def show_post(post_id):
post = next((p for p in posts if p['id'] == post_id), None)
return render_template('post.html', post=post)
@app.route('/create', methods=['GET', 'POST'])
def create_post():
if request.method == 'POST':
title = request.form['title']
content = request.form['content']
file = request.files.get('image')
new_post = {
'id': len(posts) + 1,
'title': title,
'content': content,
'image': None
}
if file:
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
new_post['image'] = filename
posts.append(new_post)
return redirect(url_for('index'))
return render_template('create.html')
if __name__ == '__main__':
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
app.run(debug=True)
案例2:REST API服务
# FastAPI数据API
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
app = FastAPI()
class Item(BaseModel):
id: int
name: str
price: float
# 模拟数据库
items_db = [
Item(id=1, name="Laptop", price=999.99),
Item(id=2, name="Mouse", price=29.99)
]
@app.get("/items/", response_model=List[Item])
async def read_items():
return items_db
@app.post("/items/", response_model=Item)
async def create_item(item: Item):
if any(i.id == item.id for i in items_db):
raise HTTPException(status_code=400, detail="ID已存在")
items_db.append(item)
return item
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: int):
item = next((i for i in items_db if i.id == item_id), None)
if item is None:
raise HTTPException(status_code=404, detail="商品未找到")
return item
# 运行: uvicorn main:app --reload
20.8 知识图谱
持续更新Python编程学习日志与技巧,敬请关注!
#编程# #学习# #python# #在头条记录我的2025#