热门课程 - 发现知识之美
学习进度

已完成: 0%

Flask Web开发框架

作者: 郑老师 更新: 2025-11-27 阅读: 难度: 高级
学习工具

. Flask 模板和静态文件

Flask 使用 Jinja2 模板引擎来渲染动态 HTML 页面,并提供了静态文件服务功能。

Jinja2 模板引擎

  • 变量替换:{{ variable }}
  • 控制结构:{% for %}, {% if %}
  • 模板继承:{% extends %}, {% block %}
  • 过滤器:{{ variable|filter }}

基本模板使用

渲染模板
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def index(): # 传递变量到模板 return render_template('index.html', title='Home Page', username='John Doe') @app.route('/users') def users(): user_list = [{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}, {'name': 'Charlie', 'age': 35}] return render_template('users.html', users=user_list) @app.route('/post/<int:post_id>') def show_post(post_id): post = {'id': post_id, 'title': f'Post {post_id}', 'content': 'This is the post content.'} return render_template('post.html', post=post)

基础模板

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 %}My Flask App{% endblock %}</title> <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"> </head> <body> <nav> <ul> <li><a href="{{ url_for('index') }}">Home</a></li> <li><a href="{{ url_for('users') }}">Users</a></li> </ul> </nav> <div class="content"> {% block content %} <!-- 子模板内容将在这里插入 --> {% endblock %} </div> <footer> <p>&copy; 2024 My Flask App</p> </footer> <script src="{{ url_for('static', filename='js/app.js') }}"></script> </body> </html>

继承模板

templates/index.html
{% extends "base.html" %} {% block title %}{{ title }}{% endblock %} {% block content %} <h1>Welcome, {{ username }}!</h1> <p>This is the home page of our Flask application.</p> <div class="user-info"> <h2>User Information</h2> <p><strong>Name:</strong> {{ username }}</p> <p><strong>Login Time:</strong> {{ current_time }}</p> </div> {% if messages %} <div class="messages"> <h3>Messages:</h3> <ul> {% for message in messages %} <li>{{ message }}</li> {% endfor %} </ul> </div> {% endif %} {% endblock %}

Jinja2 控制结构

控制结构示例
<!-- if 语句 --> {% if user %} <p>Welcome, {{ user.name }}!</p> {% elif guest %} <p>Welcome, Guest!</p> {% else %} <p>Please log in.</p> {% endif %} <!-- for 循环 --> <ul> {% for item in items %} <li>{{ loop.index }}. {{ item.name }}</li> {% else %} <li>No items found.</li> {% endfor %} </ul> <!-- 循环变量 --> <table> {% for user in users %} <tr class="{{ loop.cycle('odd', 'even') }}"> <td>{{ loop.index }}</td> <td>{{ user.name }}</td> <td>{{ user.email }}</td> </tr> {% endfor %} </table>

Jinja2 过滤器

常用过滤器
<!-- 字符串过滤器 --> <p>{{ title|upper }}</p> <p>{{ description|lower|truncate(50) }}</p> <p>{{ content|striptags }}</p> <p>{{ name|default("Anonymous") }}</p> <!-- 数字过滤器 --> <p>Price: {{ price|round(2) }}</p> <p>Items: {{ items|length }}</p> <p>Percentage: {{ value|float * 100 }}%</p> <!-- 日期过滤器 --> <p>Today: {{ current_time|datetimeformat('%Y-%m-%d') }}</p> <p>Relative: {{ post_date|timesince }}</p> <!-- 列表过滤器 --> <p>First: {{ list|first }}</p> <p>Last: {{ list|last }}</p> <p>Joined: {{ tags|join(", ") }}</p> <!-- 自定义过滤器 --> <p>{{ text|markdown }}</p> <p>{{ url|urlencode }}</p>

静态文件处理

CSS 样式文件
/* static/css/style.css */ body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f4f4f4; } nav { background-color: #333; color: white; padding: 1rem; } nav ul { list-style: none; padding: 0; margin: 0; display: flex; } nav li { margin-right: 1rem; } nav a { color: white; text-decoration: none; } .content { padding: 2rem; max-width: 1200px; margin: 0 auto; } .user-info { background: white; padding: 1rem; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
JavaScript 文件
// static/js/app.js document.addEventListener('DOMContentLoaded', function() { console.log('Flask app loaded successfully'); // 示例:添加交互功能 const buttons = document.querySelectorAll('.btn-action'); buttons.forEach(button => { button.addEventListener('click', function() { alert('Button clicked: ' + this.textContent); }); }); // AJAX 请求示例 function loadUserData(userId) { fetch(`/api/users/${userId}`) .then(response => response.json()) .then(data => { console.log('User data:', data); }); } });

自定义过滤器

创建自定义过滤器
from flask import Flask import datetime app = Flask(__name__) # 自定义过滤器 @app.template_filter('datetimeformat') def datetimeformat(value, format='%Y-%m-%d %H:%M:%S'): if isinstance(value, datetime.datetime): return value.strftime(format) return value @app.template_filter('timesince') def timesince(value): if isinstance(value, datetime.datetime): now = datetime.datetime.now() diff = now - value if diff.days > 365: return f"{diff.days // 365} years ago" elif diff.days > 30: return f"{diff.days // 30} months ago" elif diff.days > 0: return f"{diff.days} days ago" elif diff.seconds > 3600: return f"{diff.seconds // 3600} hours ago" elif diff.seconds > 60: return f"{diff.seconds // 60} minutes ago" else: return "just now" return value @app.template_filter('markdown') def markdown_filter(text): # 需要安装 markdown 库: pip install markdown import markdown return markdown.markdown(text) # 在模板中使用自定义过滤器 # {{ post.date|datetimeformat('%Y-%m-%d') }} # {{ post.date|timesince }} # {{ content|markdown }}
提示: 这是一个重要的概念,需要特别注意理解和掌握。
注意: 这是一个常见的错误点,请避免犯同样的错误。

评论

登录 后发表评论