会员模块实现

会员注册

class RegistForm(FlaskForm):
name = StringField(
label="昵称",
validators=[
DataRequired("昵称不能为空!")
],
description="昵称",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入昵称!",
}
)
email = StringField(
label="邮箱",
validators=[
DataRequired("邮箱不能为空!"),
Email("邮箱格式不正确!")
],
description="邮箱",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入邮箱!",
}
)
phone = StringField(
label="手机",
validators=[
DataRequired("手机号不能为空!"),
Regexp("1[34578]\d{9}", message="手机格式不正确!"),
Length(min=11, max=11, message="手机长度不正确!")
],
description="手机",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入手机!",
}
)
pwd = PasswordField(
label="密码",
validators=[
DataRequired("密码不能为空!")
],
description="密码",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入密码!",
}
)
repwd = PasswordField(
label="确认密码",
validators=[
DataRequired("请输入确认密码!"),
EqualTo('pwd', message="两次密码不一致!")
],
description="确认密码",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入确认密码!",
}
)
submit = SubmitField(
'注册',
render_kw={
"class": "btn btn-lg btn-success btn-block",
}
) def validate_name(self, field):
name = field.data
user = User.query.filter_by(name=name).count()
if user == 1:
raise ValidationError("昵称已经存在!") def validate_email(self, field):
email = field.data
user = User.query.filter_by(email=email).count()
if user == 1:
raise ValidationError("邮箱已经存在!") def validate_phone(self, field):
phone = field.data
user = User.query.filter_by(phone=phone).count()
if user == 1:
raise ValidationError("手机号码已经存在!")

视图函数

@home.route("/regist/", methods=["GET", "POST"])
def regist():
"""
会员注册
"""
form = RegistForm()
if form.validate_on_submit():
data = form.data
user = User(
name=data["name"],
email=data["email"],
phone=data["phone"],
pwd=generate_password_hash(data["pwd"]),
uuid=uuid.uuid4().hex
)
db.session.add(user)
db.session.commit()
flash("注册成功!", "ok")
return render_template("home/regist.html", form=form)

修改对应的前端文件

会员登录

class LoginForm(FlaskForm):
name = StringField(
label="账号",
validators=[
DataRequired("账号不能为空!")
],
description="账号",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入账号!",
}
)
pwd = PasswordField(
label="密码",
validators=[
DataRequired("密码不能为空!")
],
description="密码",
render_kw={
"class": "form-control input-lg",
"placeholder": "请输入密码!",
}
)
submit = SubmitField(
'登录',
render_kw={
"class": "btn btn-lg btn-primary btn-block",
}
)

视图函数

在登录时需要校验密码,需要在User模型中添加check_pwd函数,和admin模型中的一样

@home.route("/login/", methods=["GET", "POST"])
def login():
"""
登录
"""
form = LoginForm()
if form.validate_on_submit():
data = form.data
user = User.query.filter_by(name=data["name"]).first()
if user:
if not user.check_pwd(data["pwd"]):
flash("密码错误!", "err")
return redirect(url_for("home.login"))
else:
flash("账户不存在!", "err")
return redirect(url_for("home.login"))
session["user"] = user.name
session["user_id"] = user.id
userlog = Userlog(
user_id=user.id,
ip=request.remote_addr
)
db.session.add(userlog)
db.session.commit()
return redirect(url_for("home.user"))
return render_template("home/login.html", form=form)

在登录时添加登录日志

修改对应的前端文件

修改会员资料

class UserdetailForm(FlaskForm):
name = StringField(
label="账号",
validators=[
DataRequired("账号不能为空!")
],
description="账号",
render_kw={
"class": "form-control",
"placeholder": "请输入账号!",
}
)
email = StringField(
label="邮箱",
validators=[
DataRequired("邮箱不能为空!"),
Email("邮箱格式不正确!")
],
description="邮箱",
render_kw={
"class": "form-control",
"placeholder": "请输入邮箱!",
}
)
phone = StringField(
label="手机",
validators=[
DataRequired("手机号不能为空!"),
Regexp("1[34578]\d{9}", message="手机格式不正确!"),
Length(min=11, max=11, message="手机长度不正确!")
],
description="手机",
render_kw={
"class": "form-control",
"placeholder": "请输入手机!",
}
)
face = FileField(
label="头像",
validators=[
DataRequired("请上传头像!")
],
description="头像",
)
info = TextAreaField(
label="简介",
validators=[
DataRequired("简介不能为空!")
],
description="简介",
render_kw={
"class": "form-control",
"rows": 10
}
)
submit = SubmitField(
'保存修改',
render_kw={
"class": "btn btn-success",
}
)

视图函数

修改文件名

def change_filename(filename):
"""
修改文件名称
"""
fileinfo = os.path.splitext(filename)
filename = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + \
str(uuid.uuid4().hex) + fileinfo[-1]
return filename def user_login_req(f):
"""
登录装饰器
""" @wraps(f)
def decorated_function(*args, **kwargs):
if "user" not in session:
return redirect(url_for("home.login", next=request.url))
return f(*args, **kwargs) return decorated_function
@home.route("/user/", methods=["GET", "POST"])
@user_login_req
def user():
form = UserdetailForm()
user = User.query.get(int(session["user_id"]))
form.face.validators = []
if request.method == "GET":
# 赋初值
form.name.data = user.name
form.email.data = user.email
form.phone.data = user.phone
form.info.data = user.info
if form.validate_on_submit():
data = form.data
if form.face.data != "":
file_face = secure_filename(form.face.data.filename)
if not os.path.exists(app.config["FC_DIR"]):
os.makedirs(app.config["FC_DIR"])
os.chmod(app.config["FC_DIR"], 6)
user.face = change_filename(file_face)
form.face.data.save(app.config["FC_DIR"] + user.face) name_count = User.query.filter_by(name=data["name"]).count()
if data["name"] != user.name and name_count == 1:
flash("昵称已经存在!", "err")
return redirect(url_for("home.user")) email_count = User.query.filter_by(email=data["email"]).count()
if data["email"] != user.email and email_count == 1:
flash("邮箱已经存在!", "err")
return redirect(url_for("home.user")) phone_count = User.query.filter_by(phone=data["phone"]).count()
if data["phone"] != user.phone and phone_count == 1:
flash("手机已经存在!", "err")
return redirect(url_for("home.user")) # 保存
user.name = data["name"]
user.email = data["email"]
user.phone = data["phone"]
user.info = data["info"]
db.session.add(user)
db.session.commit()
flash("修改成功!", "ok")
return redirect(url_for("home.user"))
return render_template("home/user.html", form=form, user=user)

在初始化文件中添加app.config["FC_DIR"] = os.path.join(os.path.abspath(os.path.dirname(__file__)), "static/uploads/users/")

修改对应的前端文件

修改密码

class PwdForm(FlaskForm):
old_pwd = PasswordField(
label="旧密码",
validators=[
DataRequired("旧密码不能为空!")
],
description="旧密码",
render_kw={
"class": "form-control",
"placeholder": "请输入旧密码!",
}
)
new_pwd = PasswordField(
label="新密码",
validators=[
DataRequired("新密码不能为空!"),
],
description="新密码",
render_kw={
"class": "form-control",
"placeholder": "请输入新密码!",
}
)
submit = SubmitField(
'修改密码',
render_kw={
"class": "btn btn-success",
}
)

视图函数

@home.route("/pwd/", methods=["GET", "POST"])
@user_login_req
def pwd():
"""
修改密码
"""
form = PwdForm()
if form.validate_on_submit():
data = form.data
user = User.query.filter_by(name=session["user"]).first()
if not user.check_pwd(data["old_pwd"]):
flash("旧密码错误!", "err")
return redirect(url_for('home.pwd'))
user.pwd = generate_password_hash(data["new_pwd"])
db.session.add(user)
db.session.commit()
flash("修改密码成功,请重新登录!", "ok")
return redirect(url_for('home.logout'))
return render_template("home/pwd.html", form=form)

修改对应的前端文件

会员登录日志

登陆日志不需要表单

@home.route("/loginlog/<int:page>/", methods=["GET"])
@user_login_req
def loginlog(page=1):
"""
会员登录日志
"""
if page <= 0:
page = 1
page_data = Userlog.query.filter_by(
user_id=int(session["user_id"])
).order_by(
Userlog.addtime.desc()
).paginate(page=page, per_page=10)
return render_template("home/loginlog.html", page_data=page_data)

新建app/templates/ui/home_page.html,用来分页

{% macro page(data,url) -%}
{% if data %}
<nav aria-label="Page navigation">
<ul class="pagination">
<li><a href="{{ url_for(url,page=1) }}">首页</a></li> {% if data.has_prev %}
<li><a href="{{ url_for(url,page=data.prev_num) }}">上一页</a></li>
{% else %}
<li class="disabled"><a href="#">上一页</a></li>
{% endif %} {% for v in data.iter_pages() %}
{% if v %}
{% if v == data.page %}
<li class="active"><a href="#">{{ v }}</a></li>
{% else %}
<li><a href="{{ url_for(url,page=v) }}">{{ v }}</a></li>
{% endif %}
{% endif %}
{% endfor %} {% if data.has_next %}
<li><a href="{{ url_for(url,page=data.next_num) }}">下一页</a></li>
{% else %}
<li class="disabled"><a href="#">下一页</a></li>
{% endif %} <li><a href="{{ url_for(url,page=data.pages) }}">尾页</a></li>
</ul>
</nav>
{% endif %}
{%- endmacro %}

修改对应的前端代码,并使用这个分页

Flask 构建微电影视频网站(六)的更多相关文章

  1. Python flask 构建微电影视频网站☝☝☝

    Python flask 构建微电影视频网站☝☝☝ 1.安装数据库连接依赖包 pip install flask-sqlalchemy 2.创建movie数据库 在CentOS虚拟机,进入MaridD ...

  2. Python flask 构建微电影视频网站✍✍✍

    Python flask 构建微电影视频网站  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大 ...

  3. Flask 构建微电影视频网站(一)

    Flask构建电影视频网站 Python MTV模型 Flask微内核 Flask扩展插件配置及使用方法 根据业务开发网站前后台功能 Flask结合MySQL数据库 你将可以独立开发网站 独立部署运维 ...

  4. Python Flask 构建微电影视频网站

    前言 学完本教程,你将掌握: 1.学会使用整形.浮点型.路径型.字符串型正则表达式路由转化器 2.学会使用post与get请求.上传文件.cookie获取与相应.404处理 3.学会适应模板自动转义. ...

  5. Flask 构建微电影视频网站(四)

    后台管理 实现后台管理系统使用flask sqlalchemy结合mysql数据库进行增删改查操作.分页的使用.路由装饰器定义.模板中变量调用.登录会话机制.上传文件.flask wtforms表单使 ...

  6. Flask 构建微电影视频网站(二)

    搭建前台页面 前台布局搭建 将static中的文件拷贝到项目的static目录下 在app/templates/home下新建home.html,当作基础模板,并修改静态资源链接 <!docty ...

  7. Flask 构建微电影视频网站(八)

    评论收藏及弹幕 实现电影评论添加及列表.数据查询实现统计播放量和评论量.jquery ajax实现收藏电影,flask结合redis消息队列实现电影弹幕,bug处理等功能. 电影评论-统计 class ...

  8. Flask 构建微电影视频网站(三)

    搭建后台页面 视图函数位于admin文件夹下, app/admin/views.py 管理员登录页面搭建 视图函数 @admin.route('/') def index(): return '后台主 ...

  9. Flask 构建微电影视频网站(七)

    电影模块实现 上映预告 @home.route("/animation/") def animation(): """ 首页轮播动画 "&q ...

随机推荐

  1. Sql学习笔记(二)—— 条件查询

    上篇简单介绍了一下sql的一些基础增删改查语句,而针对多种多样的查询语句则未详细说明,这一篇继续记录一下关于各种条件查询的知识. 1.按列名进行查询 语句: select stuName , stuA ...

  2. jQuery里面的常用的事件和基础动画的实现

    一:了解jquery里面常用的事件 二:了解基础动画的实现 1:加载DOM 在JavaScript中使用window.onload事件作为窗体加载事件(它在页面所有数据加载完成之后才会执行) 在jQu ...

  3. Nginx系列

    包括nginx的入门和进阶学习. 目录 nginx系列1:认识nginx nginx系列2:搭建nginx环境 nginx系列3:搭建一个静态资源web服务器 nginx系列4:日志管理 nginx系 ...

  4. HTML中块元素与内联元素的概念

    HTML中块元素与内联元素的概念 div就是一个块元素,所谓的块元素就是会独占一行的的元素,无论他的内容有多少,他都会独占一整行. p h1 h2 h3 ... div这个标签没有任何语义,就是一个纯 ...

  5. 微信小程序之菜鸟入门教学(二)

    昨天学习了一些简单的概念,今天开始实际操作,通过搭建简单的计算器来学习小程序的架构 一.小程序框架 程序框架如上图所示.由此可见,框架的基本构成为: 1. app.js . app.wxss 2. a ...

  6. K60用IRA通过j-link下载失败,解决方法

    K60在用飞思卡尔原厂的例程时,例程编译时没有问题,但是烧写时不成功,出现以下提示,请问该如何解决这个问题?提示1.Miss or malformed flash loader specificati ...

  7. Android视频录制从不入门到入门系列教程(四)————Camera Parameter

    Camera提供了一个叫做setParameters的方法帮助开发者设置相机的相关参数. 通过Camera的getParameters方法可以获取到当前为相机设置的相关参数. 下面简单介绍下,视频录制 ...

  8. dede首页、列表页调用非缩略图

    在include/extend.func.php末尾添加 function firstimg($str_pic) { $str_sub=substr($str_pic,0,-7).strrchr($s ...

  9. CentOS 6忘记root密码的解决办法

    1.在开机启动的时候按键盘上的“E”键 或者“ESC”键,会进入如下界面 2.选择相应的内核,再次按“E”,出现下图,选择第二项,再次按“E”键 3.经过第二步,这个画面可以编辑,在信息的最后加“空格 ...

  10. 对ES6的yield示例分析

    近期ES6标准如火如荼的发展,其中主要还是各大浏览器的支持,最重要厂商支付宝,微信的支持,使得国内的发展也很迅猛. 这里主要是对yield关键字的,yield实际上可以看作是一种新的中断机制,大家都知 ...