30天学会Python编程:20. Python Web开发简介

20.1 Web基础概念

20.1.1 HTTP协议

20.1.2 请求/响应周期

  1. 客户端发送HTTP请求
  2. 服务器解析请求
  3. 应用处理业务逻辑
  4. 生成HTTP响应
  5. 返回给客户端

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#


相关文章

Deepseek分析:普通人三个月自学python能成爬出大神吗?

“零基础三个月速成爬虫大神!"--这种标题在网上一抓一大把,看得人热血沸腾。但作为一个被反爬机制虐哭、又靠爬虫转行的过来人,我必须说句实话:三个月从小白到“实战大神”是伪命题,但达到能接单、做...

30天学会Python编程:22. Python机器学习简介

22.1 机器学习概述22.1.1 机器学习分类22.1.2 典型应用场景学习类型应用案例常用算法分类垃圾邮件识别决策树/SVM回归房价预测线性回归聚类客户分群K-Means降维数据可视化PCA22....

我电子信息专业出身,给孩子换3家机构后,学Python编程真实感受

最近和几个宝妈聊天,话题绕来绕去总离不开“编程班”。有人说“现在不学编程,孩子未来要被时代淘汰”,有人抱怨“花了几万块,孩子学了半年连个小程序都写不出来”,也有人像我一样,换了3家机构才找到合适的。当...

2025年Python爬虫学习路线:从零到精通的项目驱动实践

在数据驱动的2025年,Python爬虫技术已成为获取网络数据的利器。无论是抓取电商价格、分析社交媒体趋势,还是挖掘新闻资讯,爬虫都能帮助我们高效获取信息。对于初学者而言,项目驱动的学习方式不仅能快速...

自学Python你卡在了哪一步?被卡了几次?

自学 Python 的放弃点通常集中在以下几个阶段(按学习顺序排列),结合放弃原因和应对建议整理如下:---### **1. 环境配置阶段(第1-3天)**- **放弃原因**: - 安装 Pytho...