注意

本次作业是继上次表单作业我们进行的jinja2的改造。代码量不大,注意下载好资料
需要用到的软件是hbuilder或者其他你知道的可以写html的软件,以及大家还需要下载资料当中的文件。
点击代码块,可使用方向键左右移动查看代码
注释部分是留给大家的说明学习内容,注释部分不需要敲
本次作业涉及到宏、继承的知识,非常希望大家能动手练习一下,这是本学习练习jinja2的唯一实验代码
推荐在电脑上分屏敲,一半浏览器、一半编译器
提交运行后截图,注意改脚标你的名字

1.base.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>{% block title %}注册{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='semantic.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
{# Flash 消息:for 循环渲染 #}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="flash-area">
{% for category, msg in messages %}
<div class="flash flash-{{ category }}">{{ msg }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}

{% block content %}{% endblock %}
<footer>
© 2026 |(改为你的名字)
</footer>
</body>
</html>

2.form.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{% extends "base.html" %}

{# ============== 宏定义 ============== #}
{% macro render_input(name, label, type='text', placeholder='') %}
<div>
<label>{{ label }}:</label>
<input type="{{ type }}" name="{{ name }}" placeholder="{{ placeholder }}">
</div>
{% endmacro %}

{% macro render_choice(label, name, options, type='checkbox') %}
<p>{{ label }}:
{% for opt in options %}
<input class="ui {{ type }}" type="{{ type }}" name="{{ name }}" value="{{ opt.value }}" {% if opt.selected %}checked{% endif %}>{{ opt.label }}
{% endfor %}
</p>
{% endmacro %}

{% block content %}
<div class="bg">
<video autoplay loop muted>
<source src="{{ url_for('static', filename='jett.mp4') }}" type="video/mp4">
</video>
<div class="regi">
<h1 class="regi-title">注册</h1>
<form class="form-group ui form" method="POST" action="{{ url_for('register') }}">
<fieldset>
<legend>个人资料</legend>
{{ render_input('email', '电子邮箱', 'email', '电子邮箱') }}
{{ render_input('username', '用户名', 'text', '用户名') }}
{{ render_input('password', '密码', 'password', '密码') }}
{{ render_input('birthday', '出生日期', 'date', '出生日期') }}
{{ render_choice('兴趣爱好', 'fans', [
{'value': '01', 'label': '唱歌'},
{'value': '02', 'label': '打球'},
{'value': '03', 'label': '下棋'},
{'value': '04', 'label': '上网'},
{'value': '05', 'label': '购物'},
]) }}
{{ render_choice('性别', 'sex', [
{'value': '男', 'label': '男', 'selected': True},
{'value': '女', 'label': '女'},
], 'radio') }}
</fieldset>
<fieldset>
<legend>专业与课程</legend>
<label for="">课程名:</label>
<select name="course">
{% for opt in courses %}
<option {% if opt == '大数据技术' %}selected{% endif %}>{{ opt }}</option>
{% endfor %}
</select>
&nbsp;&nbsp;
<label for="">工具软件:</label>
<input list="software">
<datalist id="software">
{% for opt in softwares %}
<option value="{{ opt.value }}">{{ opt.label }}</option>
{% endfor %}
</datalist>
</fieldset>
<div class="button-group">
<input class="ui yellow basic button" type="submit" value="提交">
<input class="ui inverted yellow button" type="reset" value="重填">
<a class="ui inverted violet button" href="{{ url_for('homepage') }}">返回首页</a>
</div>
</form>
</div>
</div>
{% endblock %}

3.homepage.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{% extends "base.html" %}

{% block title %}首页{% endblock %}

{% block content %}
<div class="home">
<h1 class="regi-title">首页</h1>

{# 成功提交过:循环展示 #}
{% if data %}
<table class="result-table">
{% for key, value in data.items() %}
<tr>
<th>{{ key }}</th>
<td>{{ value }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<p class="home-tip">还没有注册记录。</p>
{% endif %}

<div class="button-group">
<a class="ui yellow basic button" href="{{ url_for('register') }}">去注册</a>
</div>
</div>
{% endblock %}

4.app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from flask import Flask, render_template, request, redirect, url_for, session, flash

app = Flask(__name__)
app.secret_key = 'a_simple_secret_key'

COURSES = ['软件工程', '计算机应用', '大数据技术', '数据库应用基础', 'C语言', '网页设计']
SOFTWARES = [
{'value': '1', 'label': 'Kingsoft WPS'},
{'value': '2', 'label': 'MS Office'},
{'value': '3', 'label': 'Visio'},
{'value': '4', 'label': 'ToDesk'},
{'value': '5', 'label': '腾讯会议'},
]


@app.route('/')
def homepage():
return render_template('homepage.html', data=session.get('form_data'))


@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
f = request.form
errors = []

if '@' not in f.get('email', ''):
errors.append('邮箱格式不正确')
if len(f.get('username', '')) < 2:
errors.append('用户名至少 2 个字符')
if len(f.get('password', '')) < 6:
errors.append('密码至少 6 个字符')
if not f.get('birthday'):
errors.append('请选择出生日期')
if not f.getlist('fans'):
errors.append('请至少选择一个兴趣爱好')
if not f.get('sex'):
errors.append('请选择性别')
if not f.get('course'):
errors.append('请选择课程')

if errors:
for e in errors:
flash(e, 'error')
return redirect(url_for('homepage'))

session['form_data'] = f.to_dict()
flash('注册成功!', 'success')
return redirect(url_for('homepage'))

return render_template('form.html', courses=COURSES, softwares=SOFTWARES)


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