在目前已经编写的视图函数中,只考虑了代码在正常情况下的处理逻辑,并没有考虑程序运行过程中可能出现的各种异常情况及其相应的处理,例如:在长征概述页的视图函数profile_page()的处理逻辑中,如果示例数据文件cz_profile_data.json的路径正确及文件中的数据格式正确时,视图函数能将数据正确的获取并渲染到模板文件中,但是如果出现异常情况,如示例数据文件的路径错误(如:示例中的文件名拼写错误),则尝试打开长征概述页时,将会看到图1所示的页面错误信息(FileNotFoundError,前提是在app.run()方法中指定了参数debug=True);而如果文件路径正确,但是文件中的数据格式不是正确的JSON格式数据,则尝试打开长征概述页时,将会看到图2所示的页面错误信息(JSONDecodeError)。因此,在本实训中,将给长征概述页的视图函数profile_page()(项目根目录下的views/cz_profile.py文件中)添加异常处理,以提高程序的健壮性。具体步骤如下:
1. 修改cz_profile.py文件,给视图函数profile_page()添加异常处理代码,如图3所示。
import json
import os
from json import JSONDecodeError
from flask import Blueprint, render_template
from models.global_data import v_list
profile = Blueprint('profile', __name__)
@profile.route('/profile')
def profile_page():
fpath = os.path.join(os.getcwd(), "static/jsons/cz_profile_data.json") # 构造示例数据文件的路径字符串
# 用open方法,根据示例数据文件路径打开json文件,并用json模块的load方法将数据加载到相应变量中
try:
with open(fpath, mode='r', encoding='utf-8') as fp:
profiles = json.load(fp=fp)
lines = []
if profiles:
for idx, item in enumerate(profiles["czProfileArmy"]):
temp = item.split(":", 1)
line = { # 将长征中的红军队伍相关数据组织到一个列表中,以便于html页面中使用
'army': temp[0],
'desc': temp[1],
'line_img': profiles["czProfileLinePics"][idx]
}
idx += 1
lines.append(line) # 注意:原代码中的 'Line' 应为 'line'
except FileNotFoundError as fe:
print(f"文件路径:{fpath}不存在,请检查!{fe}")
profiles = lines = None
except json.JSONDecodeError as je: # 注意:原代码中的 'JSoNDecodeError' 应为 'json.JSONDecodeError'
print(f"解析文件:{fpath}出错,请检查!")
profiles = lines = None
except Exception as e:
print(f"其它异常情况:{e}")
# 利用render_template方法,将相关数据渲染到模板文件中
return render_template("index/cz_profile.html", v_list=v_list, profiles=profiles, lines=lines)
2.修改cz_profile.html模板文件(项目根目录下的templates/index/子目录中),给模板文件中添加相应的判断处理代码,如图4所示。
{% extends "/cz_base.html" %}
{% block main %}
{% if profiles %}
<!-- 长征·图片轮播 -->
<section id="myCarousel" class="carousel slide" data-bs-ride="carousel">
<ul class="carousel-indicators">
{% for v in v_list %}
{% if loop.first %}
<li data-bs-target="#myCarousel" data-bs-slide-to="{{loop.index0}}"
class="active" aria-current="true" aria-label="Slide{{loop.index}}"></li>
{% else %}
<li data-bs-target="#myCarousel" data-bs-slide-to="{{loop.index0}}"
aria-label="Slide{{loop.index}}"></li>
{% endif %}
{% endfor %}
</ul>
<div class="carousel-inner">
{% for v in v_list %}
{% if loop.first %}
<div class="carousel-item active">
<img class="d-block w-100" src="{{ url_for('static',filename=v.img_src) }}">
</div>
{% else %}
<div class="carousel-item">
<img class="d-block w-100" src="{{ url_for('static', filename=v.img_src) }}">
</div>
{% endif %}
{% endfor %}
</div>
<ul class="m-0">
<li class="carousel-control-prev" data-bs-target="#myCarousel" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
</li>
<li class="carousel-control-next" data-bs-target="#myCarousel" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
</li>
</ul>
</section>
<!-- 长征·历史背景 -->
<section class="mt-1">
<div class="container pt-4">
<div class="row">
<div class="block-title-w">
<h2 class="block-titLe">长征·历史背景</h2>
<span class="icon-title">
<span></span>
<img src="{{ url_for('static', filename='images/star.png') }}" width="30" height="30">
</span>
<img src="{{ url_for('static', filename='images/cz_bar.jpg') }}" class="rounded w-100 mt-3">
<div class="text-start">
<span class="text-danger fw-bold fs-4 mt-3">
<img src="{{ url_for('static', filename='images/cz.jpg') }}" class="rounded" height="26">
{{ profiles.czProfileSubTitle1 }}</span>
<span class="sub-title fw-bold fs-4 mt-3 text-primary">
{{ profiles.czProfileSubTitle2 }}</span>
<span class="text-warning sub-title fw-semibold fs-4 mt-3">
{{ profiles.czProfileDescription }}</span>
{% for intro in profiles.czProfileIntroduction %}
<span class="sub-title {{ loop.cycle('bg-warning', 'bg-light') }} fw-medium fs-5 mt-3 p-3 rounded-4">
{{ intro }}</span>
{% endfor %}
<h2 class="block-titLe">参考资料</h2>
{% for ref in profiles.czProfileReferences %}
<span class="sub-title bg-light fw-medium fs-5 p-3 rounded-4 mb-1">{{ ref }}</span>
{% endfor %}
</div>
</div>
</div>
</div>
</section>
<!--长征·行军路线-->
<section class="mt-1 py-4 bg-cz">
<div class="container">
<div class="block-title-w">
<h2 class="block-title">长征·行军路线</h2>
<span class="icon-title">
<span></span>
<img src="{{ url_for('static', filename='images/star.png') }}" width="30" height="30">
</span>
</div>
<div class="row mb-5">
<div class="col-md-6 col-sm-6">
<img class="img-fluid w-100 rounded-3"
src="{{ url_for('static', filename=profiles.czProfileLinePic1) }}" alt="长征路线图"/>
</div>
<div class="col-md-6 col-sm-6">
<h2 class="bLock-title fw-bolder fs-3 mb-4">基本路线</h2>
<span class="sub-title fw-bold fs-4 mt-3 text-primary">{{ profiles.czProfileBaseLine }}</span>
</div>
</div>
<h2 class="block-title fw-bolder fs-4 mt-5">红军各部长征路线</h2>
<div class="row">
{% for line in lines %}
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12 p-1">
<div class="fw-semibold fs-5 mt-2 text-primary ps-2">
<i class="bi bi-flag-fill" style="font-size:1rem;color:red;"></i>
{{ line.army }}
</div>
<img class="img-fluid w-100 rounded-3" src="{{ url_for('static', filename=line.line_img) }}"/>
<div class="cz-loss-decs">
<p>{{ line.desc }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
</section>
<!--长征·重要会议-->
<section class="mt-1 bg-army">
<div class="container py-4">
<div class="row">
<div class="block-title-w">
<h2 class="block-title">长征·重要会议</h2>
<span class="icon-title">
<span></span>
<img src="{{ url_for('static', filename='images/star.png') }}" width="30" height="30">
</span>
</div>
<div class="row">
{% for meeting in profiles.czProfileMeetings %}
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12 mb-2 p-1">
<div class="p-1 h-100 bg-light rounded-3">
<div class="fw-semibold fs-5 mt-2 text-danger ps-2">
<i class="bi bi-flag-fill" style="font-size: 1rem; color: red;"></i>
{{ loop.index }}.{{ meeting.meetingTitle }}
</div>
<p>{{ meeting.meetingDate }}</p>
<div class="cz-loss-decs">
<p>{{ meeting.meetingPDescription }}</p>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</section>
<!-- 长征·重要将领 -->
<section class="mt-1 bg-cz">
<div class="container py-4">
<div class="block-title-w">
<h2 class="block-title">长征·重要将领</h2>
<span class="icon-title">
<span></span>
<img src="{{ url_for('static', filename='images/star.png') }}" width="30" height="30">
</span>
</div>
<div class="row row-wrap">
{% for leader in profiles.czProfileLeaders %}
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12 item">
<div class="inner mb-3">
<a class="image" href="#">
<img src="{{ url_for('static', filename=leader) }}" class="img-fluid w-100" alt="长征将领">
</a>
</div>
</div>
{% endfor %}
</div>
</div>
</section>
<!-- 长征·名称由来 -->
<section class="mt-1 bg-cz">
<div class="container">
<div class="row">
<div class="block-title-w">
<h2 class="block-title">长征·名称由来</h2>
<span class="icon-title">
<span></span>
<img src="{{ url_for('static', filename='images/star.png') }}" width="30" height="30">
</span>
<div class="text-start fw-semibold">
{% for intro in profiles.czProfileOriginal %}
<span class="sub-title {{ loop.cycle('bg-warning', 'bg-light') }} fs-5 mt-3 p-3 rounded-4">
{{ intro }}
</span>
{% endfor %}
</div>
</div>
</div>
</div>
</section>
{% else %}
<h2 class="text-center m-5 p-5">对不起,你要査看的长征概述信息暂时出走了...</h2>
{% endif %}
{% endblock %}
3.当视图函数中加载数据出现异常时,页面的运行效果如图5所示。