Python教程(三十三):Web开发基础_python进行web开发
off999 2025-09-01 11:22 67 浏览 0 评论
今日目标
o 理解Web开发的基本概念
o 掌握Flask框架的使用
o 学会创建路由和视图函数
o 了解模板渲染和表单处理
o 掌握Flask应用的基本结构
Web开发概述
Web开发是创建网站和Web应用程序的过程:
o 前端:用户界面(HTML、CSS、JavaScript)
o 后端:服务器端逻辑(Python、数据库)
o HTTP协议:客户端和服务器之间的通信协议
o Web框架:简化Web开发的工具集
Web应用的基本流程
# 简化的Web应用流程
def web_application_flow():
"""
1. 客户端发送HTTP请求
2. 服务器接收请求
3. 路由系统找到对应的处理函数
4. 处理函数执行业务逻辑
5. 返回HTTP响应(HTML、JSON等)
"""
passFlask框架介绍
Flask是一个轻量级的Python Web框架,具有以下特点:
o 微框架:核心简单,易于扩展
o 灵活性:不强制特定的项目结构
o 易学易用:学习曲线平缓
o 丰富的扩展:支持各种功能扩展
安装Flask
pip install flaskFlask基础
1. 第一个Flask应用
from flask import Flask
# 创建Flask应用实例
app = Flask(__name__)
# 定义路由和视图函数
@app.route('/')
def hello_world():
return 'Hello, World!'
@app.route('/about')
def about():
return '这是关于页面'
@app.route('/user/<username>')
def show_user_profile(username):
return f'用户: {username}'
if __name__ == '__main__':
app.run(debug=True)2. 路由系统
from flask import Flask, request
app = Flask(__name__)
# 基本路由
@app.route('/')
def index():
return '首页'
# 带参数的路由
@app.route('/user/<username>')
def user_profile(username):
return f'用户资料: {username}'
# 指定参数类型
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'文章ID: {post_id} (类型: {type(post_id)})'
# 多个参数
@app.route('/user/<username>/posts/<int:post_id>')
def user_post(username, post_id):
return f'用户 {username} 的文章 {post_id}'
# HTTP方法
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return '处理登录请求'
else:
return '显示登录表单'
# 默认值
@app.route('/page/')
@app.route('/page/<int:page_num>')
def show_page(page_num=1):
return f'显示第 {page_num} 页'
if __name__ == '__main__':
app.run(debug=True)3. 请求和响应
from flask import Flask, request, jsonify, make_response
app = Flask(__name__)
@app.route('/api/data', methods=['GET', 'POST'])
def handle_data():
if request.method == 'GET':
# 获取查询参数
name = request.args.get('name', '默认名称')
age = request.args.get('age', 0, type=int)
# 返回JSON响应
return jsonify({
'name': name,
'age': age,
'message': 'GET请求成功'
})
elif request.method == 'POST':
# 获取表单数据
form_data = request.form
name = form_data.get('name', '')
email = form_data.get('email', '')
# 获取JSON数据
json_data = request.get_json()
# 获取文件
file = request.files.get('file')
return jsonify({
'form_data': dict(form_data),
'json_data': json_data,
'file_name': file.filename if file else None,
'message': 'POST请求成功'
})
@app.route('/custom-response')
def custom_response():
# 创建自定义响应
response = make_response('自定义响应内容')
response.headers['Content-Type'] = 'text/plain'
response.headers['X-Custom-Header'] = '自定义头部'
return response
@app.route('/redirect-example')
def redirect_example():
# 重定向
from flask import redirect, url_for
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)模板系统
1. 基本模板渲染
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
# 传递数据到模板
user = {
'name': '张三',
'age': 25,
'email': 'zhangsan@example.com'
}
posts = [
{'title': '第一篇文章', 'content': '这是第一篇文章的内容'},
{'title': '第二篇文章', 'content': '这是第二篇文章的内容'},
{'title': '第三篇文章', 'content': '这是第三篇文章的内容'}
]
return render_template('index.html', user=user, posts=posts)
@app.route('/user/<username>')
def user_profile(username):
return render_template('user.html', username=username)
if __name__ == '__main__':
app.run(debug=True)2. 模板文件示例
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<header>
<nav>
<a href="{{ url_for('index') }}">首页</a>
<a href="{{ url_for('about') }}">关于</a>
</nav>
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>(c) 2024 Flask应用</p>
</footer>
</body>
</html><!-- templates/index.html -->
{% extends "base.html" %}
{% block title %}首页{% endblock %}
{% block content %}
<div class="container">
<h1>欢迎, {{ user.name }}!</h1>
<div class="user-info">
<p>年龄: {{ user.age }}</p>
<p>邮箱: {{ user.email }}</p>
</div>
<h2>文章列表</h2>
<div class="posts">
{% for post in posts %}
<article class="post">
<h3>{{ post.title }}</h3>
<p>{{ post.content }}</p>
</article>
{% endfor %}
</div>
{% if posts|length > 2 %}
<p>共有 {{ posts|length }} 篇文章</p>
{% endif %}
</div>
{% endblock %}<!-- templates/user.html -->
{% extends "base.html" %}
{% block title %}{{ username }}的页面{% endblock %}
{% block content %}
<div class="container">
<h1>{{ username }}的个人页面</h1>
<p>这是 {{ username }} 的个人资料页面。</p>
</div>
{% endblock %}3. 模板语法
<!-- 模板语法示例 -->
{% comment %}
Jinja2模板语法
{% endcomment %}
<!-- 变量输出 -->
<p>{{ user.name }}</p>
<p>{{ user['age'] }}</p>
<!-- 条件语句 -->
{% if user.age >= 18 %}
<p>成年人</p>
{% elif user.age >= 12 %}
<p>青少年</p>
{% else %}
<p>儿童</p>
{% endif %}
<!-- 循环语句 -->
{% for item in items %}
<li>{{ item }}</li>
{% else %}
<li>没有项目</li>
{% endfor %}
<!-- 过滤器 -->
<p>{{ user.name|upper }}</p>
<p>{{ user.name|length }}</p>
<p>{{ user.name|default('匿名用户') }}</p>
<!-- 宏定义 -->
{% macro input(name, value='', type='text') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}
<!-- 使用宏 -->
{{ input('username') }}
{{ input('password', type='password') }}
<!-- 包含其他模板 -->
{% include 'header.html' %}
<!-- 设置变量 -->
{% set title = '页面标题' %}
<h1>{{ title }}</h1>表单处理
1. 基本表单
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, Length
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here'
# 定义表单类
class LoginForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired(), Length(min=3, max=20)])
password = PasswordField('密码', validators=[DataRequired(), Length(min=6)])
submit = SubmitField('登录')
class RegistrationForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired(), Length(min=3, max=20)])
email = StringField('邮箱', validators=[DataRequired(), Email()])
password = PasswordField('密码', validators=[DataRequired(), Length(min=6)])
confirm_password = PasswordField('确认密码', validators=[DataRequired()])
submit = SubmitField('注册')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
# 处理登录逻辑
username = form.username.data
password = form.password.data
# 这里应该验证用户名和密码
if username == 'admin' and password == 'password':
flash('登录成功!', 'success')
return redirect(url_for('index'))
else:
flash('用户名或密码错误!', 'error')
return render_template('login.html', form=form)
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
# 验证密码确认
if form.password.data != form.confirm_password.data:
flash('密码不匹配!', 'error')
return render_template('register.html', form=form)
# 处理注册逻辑
username = form.username.data
email = form.email.data
password = form.password.data
# 这里应该保存用户数据到数据库
flash(f'用户 {username} 注册成功!', 'success')
return redirect(url_for('login'))
return render_template('register.html', form=form)
if __name__ == '__main__':
app.run(debug=True)2. 表单模板
<!-- templates/login.html -->
{% extends "base.html" %}
{% block title %}登录{% endblock %}
{% block content %}
<div class="container">
<h1>用户登录</h1>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.username.label }}
{{ form.username(class="form-control") }}
{% if form.username.errors %}
{% for error in form.username.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
{% endif %}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password(class="form-control") }}
{% if form.password.errors %}
{% for error in form.password.errors %}
<span class="error">{{ error }}</span>
{% endfor %}
{% endif %}
</div>
{{ form.submit(class="btn btn-primary") }}
</form>
<p>还没有账号?<a href="{{ url_for('register') }}">立即注册</a></p>
</div>
{% endblock %}静态文件
1. 静态文件结构
your_app/
├── static/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
├── templates/
│ └── ...
└── app.py2. CSS样式示例
/* static/css/style.css */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
background-color: #333;
color: white;
padding: 1rem;
}
nav a {
color: white;
text-decoration: none;
margin-right: 20px;
}
nav a:hover {
color: #ddd;
}
.form-group {
margin-bottom: 15px;
}
.form-control {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.alert {
padding: 10px;
margin-bottom: 15px;
border-radius: 4px;
}
.alert-success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.alert-error {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.post {
background-color: white;
padding: 15px;
margin-bottom: 15px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}错误处理
from flask import Flask, render_template
app = Flask(__name__)
@app.errorhandler(404)
def not_found_error(error):
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_error(error):
return render_template('500.html'), 500
@app.errorhandler(403)
def forbidden_error(error):
return render_template('403.html'), 403
# 自定义错误页面模板<!-- templates/404.html -->
{% extends "base.html" %}
{% block title %}页面未找到{% endblock %}
{% block content %}
<div class="container">
<h1>404 - 页面未找到</h1>
<p>抱歉,您访问的页面不存在。</p>
<a href="{{ url_for('index') }}">返回首页</a>
</div>
{% endblock %}应用配置
from flask import Flask
app = Flask(__name__)
# 配置选项
app.config['SECRET_KEY'] = 'your-secret-key-here'
app.config['DEBUG'] = True
app.config['TESTING'] = False
app.config['DATABASE'] = 'path/to/database.db'
# 或者使用配置文件
class Config:
SECRET_KEY = 'your-secret-key-here'
DEBUG = True
DATABASE = 'path/to/database.db'
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
# 根据环境选择配置
import os
if os.environ.get('FLASK_ENV') == 'production':
app.config.from_object(ProductionConfig)
else:
app.config.from_object(DevelopmentConfig)项目结构
my_flask_app/
├── app/
│ ├── __init__.py
│ ├── models.py
│ ├── views.py
│ ├── forms.py
│ └── utils.py
├── static/
│ ├── css/
│ ├── js/
│ └── images/
├── templates/
│ ├── base.html
│ ├── index.html
│ └── user.html
├── config.py
├── requirements.txt
└── run.py今日总结
今天我们学习了Flask Web开发的基础知识:
1. Flask框架基础:应用创建、路由系统、请求响应
2. 模板系统:Jinja2模板、模板继承、模板语法
3. 表单处理:WTForms、表单验证、CSRF保护
4. 静态文件:CSS、JavaScript、图片管理
5. 错误处理:自定义错误页面
6. 应用配置:环境配置、项目结构
Flask是一个优秀的Web开发入门框架,掌握这些基础知识可以开始构建简单的Web应用。
相关推荐
- 安全教育登录入口平台(安全教育登录入口平台官网)
-
122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...
- 大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)
-
大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...
-
- 哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
-
要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...
-
2026-02-04 09:03 off999
- 电信宽带测速官网入口(电信宽带测速官网入口app)
-
这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...
- 植物大战僵尸95版手机下载(植物大战僵尸95 版下载)
-
1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...
- 免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)
-
1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...
- 2025世界杯赛程表(2025世界杯在哪个国家)
-
2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...
- 下载搜狐视频电视剧(搜狐电视剧下载安装)
-
搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...
- 永久免费听歌网站(丫丫音乐网)
-
可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...
- 音乐格式转换mp3软件(音乐格式转换器免费版)
-
有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...
- 电子书txt下载(免费的最全的小说阅读器)
-
1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...
- 最好免费观看高清电影(播放免费的最好看的电影)
-
在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...
- 孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)
-
要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
win7系统还原步骤图解(win7还原电脑系统的步骤)
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
16949认证费用是多少(16949审核员太难考了)
-
linux软件(linux软件图标)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
windows7旗舰版多少钱(win7旗舰版要多少钱)
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
