会员模块实现

会员注册

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. .NET Framework框架介绍

    1.内容 .net framework c#和.net关系 掌握C#中命名空间2..net 就是微软提供的一个开发平台 版本: vs2008 3.5 vs2010 4.0 vs2012 2013 20 ...

  2. Java运行时环境---ClassLoader类加载机制

    背景:听说ClassLoader类加载机制是进入BAT的必经之路. ClassLoader总述: 普通的Java开发其实用到ClassLoader的地方并不多,但是理解透彻ClassLoader类的加 ...

  3. 如何将数据库中的值经过servlet传入到jsp页面,并且用EL表达式显示出值

    方法一:通过id查询某一数据库表中具体的行,将值封装在相应的对象中,如下面的对象Notice servlet中 String noticeId=request.getParameter("n ...

  4. GraphQL基础篇

    最近参与了一个大型项目,大型项目随着系统业务量的增大,不同的应用和系统共同使用着许多的服务接口API,而随着业务的变化和发展,不同的应用对相同资源的不同使用方法最终会导致需要维护的服务API数量呈现爆 ...

  5. 山西大同大学教务处学生端--送给学弟,学妹的礼物,可在PC端,手机端操作

    解决问题:大同大学教务处官网学生端口一进去就卡住了,点上面一行的菜单无响应 转眼已是四年,想想自己大学即将结束,不由得让人感慨啊.这才刚开学几天,我就听到有同学在因为补考,选课的事情发愁.学校官方的教 ...

  6. 共创力董事长杨学明先生受邀参加CED智慧大会!

    2018年11月14日, 深圳市共创力咨询董事长.深圳市汇成研发管理咨询公司董事长杨学明先生受邀参加由深圳图书馆主办,深圳手讯视频承办的“倾听行业之声”2018第二届世界CED智慧大会,此次分享的主题 ...

  7. Redmine入门-安装

    Redmine提供了两种方式安装,如果仅仅只是使用Redmine,建议采用一键安装的方式,快捷方便.如果需要做二次开发或者更多的个性化处理,可以采用源码安装方式,下面分别介绍两种安装方式. ----- ...

  8. 剑指offer:调整数组顺序使奇数位于偶数前面

    题目 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 分析 事实上,这个题比较简单,很多种方式都可以实现,但是其时间复杂度或空间复 ...

  9. [LeetCode] 22. 括号生成

    题目链接:https://leetcode-cn.com/problems/generate-parentheses/ 题目描述: 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能 ...

  10. [LeetCode] 19. 删除链表的倒数第N个节点

    题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/ 题目描述: 给定一个链表,删除链表的倒数第 n 个节点, ...