目录
前言
一、各板块介绍
1.注册板块
2.登录板块
3.系统首页
4.用户管理模块
5.今日天气模块
6.大屏展示模块
二、各板块的关键思路及代码
1.注册板块关键思路及代码
2.登录板块关键思路及设计
3.首页板块的思路及设计
4.用户管理板块的思路及设计
5. 今日天气模块思路及设计
6 大屏展示模块思路及设计
总结
前言
很久没有发项目了,今天给大家分享一个自己的项目,首先介绍一下使用到了哪些技术,方便各位读者按需所取,后端采用的是Python的Flask框架,前端采用的则是HTML+CSS+JS和Echarts图表,数据库则采用的是Mysql,数据来源则是采用爬虫爬取的,下面我将详细介绍该项目。
一、各板块介绍
1.注册板块
该板块的注册可以采用邮箱的方式注册,如输入一个邮箱账号后在,后端的账户会发送一个邮箱验证码给正在注册的账号,注册的用户输入验证码之后在输入密码和确认密码之点击注册,则会提示注册成功,注册成功之后就可以进行下一步的登录。
2.登录板块
下图为登录界面,如果用户没有账号则点击下面的注册,步骤为上一个步骤的注册,当用户输入正确的账号密码后则可进入系统。
3.系统首页
第一张图为首页原图,方便各位读者观看,第二张图详细的介绍了各个板块的功能及意义了,并且数据都是通过爬取——>清洗——>保存到数据库——>从数据库中读——>呈现。
4.用户管理模块
该模块可以管理注册该系统的用户,当然肯定是只有管理员账户才能看到该页面,这里我设置的为自己的qq邮箱为管理员账号,若非管理员账户点击该页面则会提示只有管理员才能访问该页面。
5.今日天气模块
该模块采用了实时更新模式,当气象局的数据有改动时,这个地方也会随之改动,爬虫每隔一段时间就回去采取数据,下图显示了当日的湿度、温度、云量、风速,并且有小图片显示当天的气温情况是晴天或是下雨等。
6.大屏展示模块
该模块仅共于观赏,因为懒得去连后端的数据,连接数据与首页使用的技术差不多,所以这里仅仅是有这个模块,没有去完善,后面有需求的读者可以再去修改或丢弃该板块。
二、各板块的关键思路及代码
1.注册板块关键思路及代码
注册板块首先需要使用一个邮箱账号作为发送验证码的账号,需要在qq邮箱内进行配置,具体如何配置我将另在另外的文章介绍到。其次就是数据库,首先需要创建ORM类代码如下:
当创建好后,通过迁移三部曲 :1.初始化 ,2.生成迁移脚本文件,3运行迁移脚本同步到数据库 · 1.flask db init 2.flask db migrate 3.flask db upgrad
后端关键代码如下:
class EmilCaptchaModel(db.Model):
__tablename__ = "email_captcha"
# 序号
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# 邮箱
email = db.Column(db.String(100), nullable=False, unique=True)
# 验证码
captcha = db.Column(db.String(100), nullable=False)
# 创建时间
create_time = db.Column(db.DateTime, default=datetime.now)
class UserModel(db.Model):
__tablename__ = "user"
# 序号
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# 用户名
username = db.Column(db.String(200), nullable=False, unique=True)
# 邮箱
email = db.Column(db.String(100), nullable=False, unique=True)
# 密码
password = db.Column(db.String(200), nullable=False)
# 注册时间
join_time = db.Column(db.DateTime, default=datetime.now)
前端关键代码如下:
<form method="POST" accept="{{ url_for('user.register') }}">
<div>
<label>邮箱:
<input type="email" name="email" required="required" checked="checked"
oninvalid="setCustomValidity('邮箱不能为空')">
</label>
</div>
<div>
<label>用户名:
<input type="text" name="username" required="required" oninvalid="setCustomValidity('用户名不能为空')">
</label>
</div>
<div>
<label>验证码:
<input type="text" name="captcha" required="required" oninvalid="setCustomValidity('验证码不能为空')">
<button type="button" class="getVerification" id="captcha-btn">获取验证码</button>
</label>
</div>
<div>
<label>密码:
<input type="password" name="password" required="required" minlength="6" maxlength="12"
oninvalid="setCustomValidity('密码长度大于6位,小于12位,且不能为空')">
</label>
</div>
<div>
<label>确认密码:
<input type="password" name="password_confirm" required="required" minlength="6" maxlength="12"
oninvalid="setCustomValidity('密码长度大于6位,小于12位,且不能为空')">
</label>
</div>
<div class="rg">
{% for message in get_flashed_messages() %}
<p class="reminder">{{ message }}</p>
{% endfor %}
<input type="submit" value="注册" id="register">
</div>
<p>已有账号</p>
<a href="{{ url_for('user.login') }}">去登录</a>
</form>
2.登录板块关键思路及设计
当用户输入账户和密码后,首先在前端进行初步判断账号与密码是否合法,最后在到数据库中进行匹配,并且用户的密码是经过加密的,在登录时需要对密码进行解密匹配。
后端关键代码如下:
@bp.route("/login", methods=["GET", "POST"])
def login():
if request.method == "GET":
return render_template("login.html")
else:
form = LoginForm(request.form)
if form.validate():
email = form.email.data
password = form.password.data
user = UserModel.query.filter_by(email=email).first()
if user and check_password_hash(user.password, password):
# print(user)
session['user_id'] = user.id
return redirect("/")
else:
flash("邮箱或密码不匹配")
return redirect(url_for("user.login"))
else:
flash("邮箱或密码错误")
return redirect(url_for("user.login"))
前端关键代码如下:
<div class="login">
<h2>登录</h2>
<form action="{{ url_for('user.login') }}" method="POST">
<div>
<label>邮箱:
<input type="email" name="email" required="required">
</label>
</div>
<div>
<label>密码:
<input type="password" name="password" required="required">
</label>
</div>
{% for message in get_flashed_messages() %}
<p class="reminder">{{ message }}</p>
{% endfor %}
<div class="dl">
<input type="submit" value="登录">
</div>
</form>
<p>没有账号?</p>
<a href="{{ url_for('user.register') }}">注册</a>
</div>
3.首页板块的思路及设计
首先首页是页面的主题,所以需要排版美观且数据有效展示,首页的后端数据之间须有一定的联系,才能让用户能理解这些数据到底是干什么的,前端则需要做到配色不混乱让用户第一眼看到就有种赏心悦目的感觉。
后端关键代码如下(代码过多粘一小部分):
def weather(weatherdt, datayear):
result_cont = conn.execute(
"select COUNT(`每天天气情况`) FROM weatherdata WHERE `每天天气情况`='" +
weatherdt+"' AND `年` ='"+str(datayear)+"'"
)
weatherYearCount.append(result_cont.fetchone()[0])
sunnyCount = []
def weatheryear(week, datayear):
result_cont = conn.execute(
"select COUNT(`每天天气情况`) FROM weatherdata WHERE `每天天气情况`='晴' AND `年` ='"+str(
datayear)+"' AND `星期`= '"+str(week)+"'"
)
sunnyCount.append(result_cont.fetchone()[0])
week_list = ['Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday', 'Sunday']
前端关键代码(代码过多粘一小部分):
<div class="user_model">
<div class="admin">
{% if user %}
<h1>{{ user.username }}</h1>
{% else %}
<h1>未登录</h1>
<p></p>
{% endif %}
</div>
<div class="loginTime">
{% if user %}
<p class="lastTime">注册时间:</p>
<p class="getTime">{{ user.join_time }}</p>
{% else %}
<p class="lastTime">注册时间:</p>
<p class="getTime">未知</p>
{% endif %}
</div>
</div>
4.用户管理板块的思路及设计
该模块可以对用户进行管理,前提是需要唯一的管理员账号,使用管理员账号对用户进行管理,可以看到所有注册了的用户账号以及用户名,这个模块也是我偶然想到,只做了用户的删除,其余的修改和添加没有做(主要原因 懒 (❁´◡`❁) )。
后端关键代码如下(代码过多粘一小部分):
if hasattr(g, "user"):
engine = db.get_engine()
with engine.connect() as conn:
result = conn.execute(
"select username,join_time, email FROM user;")
user = result.fetchall()
data = {
"user": user,
}
return render_template('user.html', **data)
else:
return redirect(url_for("user.login"))
前端关键代码(代码过多粘一小部分):
<div class="user">
<ul class="ul">
<li>邮箱<p>用户名</p>
<p>注册时间</p>
</li>
{% for i in user %}
<li>{{ i[2] }} <p>{{ i[1] }}</p>
<p>{{ i[0] }}</p><input type="button" value="删除" id="dlt">
</li>
{% endfor %}
</ul>
</div>
5. 今日天气模块思路及设计
该模块首先需要爬虫进行实时的爬取数据,每隔一段时间就去爬取目标网站一次,这需要使用到定时器,当爬取后前端也需要每隔一段时间更新页面数据且刷新当前的页面因为浏览器的运行机制,感兴趣的可以去搜搜浏览器的运行机制,总之前端与后端都需要用到定时器,且每隔一段时间去执行一次任务。
后端关键代码如下(代码过多粘一小部分):
if hasattr(g, "user"):
engine = db.get_engine()
with engine.connect() as conn:
result = conn.execute("select * FROM todayweather")
todayweather = result.fetchall()
def TDweather(x):
dt_list = []
for i in range(len(todayweather)):
dt_list.append(todayweather[i][x])
return dt_list
# 字符串数组转化字符串
time = TDweather(1)
weather = TDweather(2)
temperature = list(map(float, TDweather(3)))
rain = TDweather(4)
wind_speed = list(map(float, TDweather(5)))
wind_direction = TDweather(6)
air_pressure = list(map(float, TDweather(7)))
humidity = list(map(float, TDweather(8)))
cloudage = list(map(float, TDweather(9)))
todayData = {
"time": time,
"weather": weather,
"temperature": temperature,
"rain": rain,
"wind_speed": wind_speed,
"wind_direction": wind_direction,
"air_pressure": air_pressure,
"humidity": humidity,
"cloudage": cloudage,
}
return render_template('weather.html', **todayData)
else:
return redirect(url_for("user.login"))
前端关键代码(代码过多粘一小部分):
<div class="weather">
<ul class="weather">
{% for i in weather %}
<li><img src="{{ url_for('static',filename='img/'+i) }}"></li>
{% endfor %}
</ul>
</div>
6 大屏展示模块思路及设计
该模块则使用的都是Echarts图表,后端没有进行数据的连接主要原因为(懒 (❁´◡`❁))故此模块就是静态网页,主要是为了可以进行大屏可视化展示,才添加的该模块。
前端关键代码(代码过多粘一小部分):
<div class="column">
<div class="panel bar">
<h2>饼图-天气</h2>
<div class="chart"></div>
<div class="panel_footer"></div>
</div>
<div class="panel line">
<h2>柱形图-天气</h2>
<div class="chart"></div>
<div class="panel_footer"></div>
</div>
<div class="panel candlestick">
<h2>柱形图-天气</h2>
<div class="chart"></div>
<div class="panel_footer"></div>
</div>
</div>
总结
此项目主要锻炼前端页面的布局方式,以及css的美化,和js后端数据的处理传入到前端,以及Flask框架的使用以及网页的爬取更锻炼了数据库的操作能力,下面我将整个项目的资源放到下面。欢迎各位大佬批评指正,如有需要该项目的读者可以点击下方连接下载也可私信我,谢谢,创作不易一键三连!
ヾ(≧▽≦*)oヾ(≧▽≦*)oヾ(≧▽≦*)oヾ(≧▽≦*)oヾ(≧▽≦*)o
整个项目资源: 重庆天气资源的完整项目包资源-CSDN文库