这部分实现后台功能(主页,用户注册,登陆,注销,查看用户信息,修改密码,查看用户评论,查看用户日志,查找电影,观看电影)
1.编辑表单(forms)
class BaseForm(FlaskForm):
username = StringField(
label="用户名",
validators=[
DataRequired()
]
)
password = PasswordField(
label="密码",
validators=[
DataRequired(),
Length(6, 12, message="密码长度必须为6-12")
]
)
class LoginForm(BaseForm):
submit = SubmitField(
label="登录"
)
class RegisterForm(BaseForm):
repassword = PasswordField(
label="确认密码",
validators=[
EqualTo('password', message="两次密码不一致")
]
)
email = StringField(
label="邮箱",
validators=[
Email(message="邮箱格式不正确")
]
)
submit = SubmitField(
label="注册"
)
class EditUserForm(FlaskForm):
username = StringField(
label="用户名",
validators=[
DataRequired()
]
)
email = StringField(
label="邮箱",
# validators=[
# Email(message="邮箱格式不正确")
# ]
)
phone = StringField(
label="电话",
# validators=[
# Regexp(r'1\d{10}', message="电话号码格式不正确")
# ]
)
face = FileField(
label="用户头像",
validators=[
# *******限制用户上传文件的格式
FileAllowed(['png', 'jpg'], message="用户头像格式错误, 必须为png或者jpg")
]
)
info = TextAreaField(
label="用户简介",
)
submit = SubmitField(
label="更新信息"
)
class PwdForm(FlaskForm):
old_pwd = PasswordField(
label="旧密码",
validators=[
DataRequired()
],
# <input name="xxx" placeholder="">
render_kw = {
'placeholder' : "请输入旧密码"
}
)
new_pwd = PasswordField(
label="新密码",
validators=[
DataRequired()
],
render_kw={
'placeholder': "请输入新密码"
}
)
submit = SubmitField(
label="修改密码"
)
2. 导入蓝图,填写视图函数(views)
@home.route('/')
@home.route('/<int:page>/')
def index(page=1):
page_movies = Movie.query.paginate(page, per_page=app.config['PER_PAGE'])
previews = Preview.query.all()
return render_template('home/index.html',
page_movies=page_movies,
app=app,
previews=previews)
# 注册页面
@home.route('/register/', methods=['POST', 'GET'])
def register():
form = RegisterForm()
if form.validate_on_submit():
# 1. 从前端获取用户输入的值;
email = form.email.data
username = form.username.data
password = form.password.data
# 2. 判断用户是否已经存在? 如果返回位None,说明可以注册;
u = User.query.filter_by(name=username).first()
if u:
flash("用户%s已经存在" % (u.name))
return redirect(url_for('home.register'))
else:
u = User(name=username, email=email)
u.password = generate_password_hash(password) # 对于密码进行加密
db.session.add(u)
db.session.commit()
flash("注册用户%s成功" % (u.name))
return redirect(url_for('home.login'))
return render_template('home/register.html',
form=form)
@home.route('/login/', methods=['POST', 'GET'])
def login():
from app.models import User, Userlog
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
user = User.query.filter_by(name=username).first()
if user and user.verify_password(password):
# session信息的保存
session['user_id'] = user.id
session['user'] = user.name
flash("用户%s登录成功" % (user.name))
remote_ip = request.remote_addr
# 将登录信息写到日志中;
userlog = Userlog(user_id=user.id,
ip=remote_ip,
area='xxx内网IP')
db.session.add(userlog)
db.session.commit()
# 从index蓝图里面寻找index函数;
return redirect(url_for('home.user'))
else:
flash("用户登录失败")
return redirect(url_for('home.login'))
return render_template('home/login.html',
form=form)
@home.route('/logout/')
@is_login
def logout():
session.pop('user_id', None)
session.pop('user', None)
return redirect(url_for('home.login'))
@home.route('/user/', methods=['GET', 'POST'])
@is_login
def user():
form = EditUserForm()
# 先在页面表单显示用户已经填写的信息
user = User.query.filter_by(name=session.get('user')).first()
form.username.data = user.name
form.email.data = user.email
form.phone.data = user.phone
if form.validate_on_submit():
# request.form - 获取表单填写的内容
username = request.form['username']
email = request.form['email']
phone = request.form['phone']
info = request.form['info']
# 1. 判断更改的用户名是否已经存在; --- 邮箱和电话自己判断, 此处省略
if username != user.name and \
User.query.filter_by(name=username).count():
flash("用户名%s已经存在" % (username))
return redirect(url_for('home.user'))
if User.query.filter_by(email=email).count() and \
email != user.email:
flash("邮箱%s已经注册" % (email))
return redirect(url_for('home.user'))
# 保存更改的信息到数据库中;(难点: 存储用户头像)
# *****存储用户的头像;
file_save_path = app.config['FC_DIR']
if not os.path.exists(file_save_path):
os.makedirs(file_save_path)
# 判断是否上传了新的头像;
if form.face.data:
# 判断之前是否已经有用户头像, 如果有, 则删除;
if user.face and os.path.exists(os.path.join(file_save_path, user.face)):
print(user.face)
os.remove(os.path.join(file_save_path, user.face)) # 删除旧头像
# 保存新的头像, 获取用户头像文件的文件名
face_name = form.face.data.filename
face_name = change_filename(face_name)
print(face_name)
# 保存新的头像文件
form.face.data.save(os.path.join(file_save_path, face_name))
user.face = face_name
user.name = username
user.email = email
user.phone = phone
user.info = info
db.session.add(user)
db.session.commit()
flash("修改会员信息成功")
# ******修改用户信息, 如果修改的是用户名, 一定要登录出, 再重新登录。
logout()
return redirect(url_for('home.login'))
return render_template('home/user.html',
form=form)
# 修改密码
@home.route('/pwd/', methods=['GET', 'POST'])
def pwd():
form = PwdForm()
if form.validate_on_submit():
# 获取当前登录用户的密码
user = User.query.filter_by(name=session.get('user')).first()
print(session.get('name'))
# 判断用户的旧密码是否正确
if user.verify_password(form.old_pwd.data):
# ********数据库里面的是password
user.password = generate_password_hash(form.new_pwd.data)
db.session.add(user)
db.session.commit()
flash("密码更新成功")
else:
flash("旧密码错误, 请重新输入")
return redirect(url_for('home.pwd'))
return render_template('home/pwd.html', form=form)
@home.route('/comments/')
@home.route('/comments/<int:page>/')
def comments(page=1):
commentsPageObj = Comment.query.filter_by(user_id=session.get('user_id')
).paginate(page, per_page=app.config['PER_PAGE'])
return render_template('home/comments.html',
commentsPageObj=commentsPageObj)
# 记录用户登录日志
@home.route('/userlog/')
@home.route('/userlog/<int:page>/')
def userlog(page=1):
userlogsPageObj = Userlog.query.filter_by(user_id=session.get('user_id')
).paginate(page, per_page=app.config['PER_PAGE'])
return render_template('home/userlog.html',
userlogsPageObj=userlogsPageObj)
@home.route('/moviecollect/')
@home.route('/moviecollect/<int:page>/')
def moviecollect(page=1):
moviecollectsPageObj = MovieCollect.query.filter_by(user_id = session.get('user_id')
).paginate(page, per_page=app.config['PER_PAGE'])
return render_template('home/moviecollect.html',
moviecollectsPageObj=moviecollectsPageObj
)
@home.route('/play/<int:id>')
def play(id):
return render_template('home/play.html')
3. 编写逻辑时用到的函数(utils)
# 判断用户是否登陆
def is_login(f):
@wraps(f)
def wrapper(*args, **kwargs):
# 判断session对象中是否有seesion['user'],
# 如果包含信息, 则登录成功, 可以访问主页;
# 如果不包含信息, 则未登录成功, 跳转到登录界面;;
if session.get('user', None):
return f(*args, **kwargs)
else:
flash("用户必须登录才能访问%s" % (f.__name__))
return redirect(url_for('home.login'))
return wrapper
# 在保存与删除用户头像时,为防止重名
def change_filename(filename):
"""在原有文件的基础上添加时间标签"""
from datetime import datetime
return datetime.now().strftime('%Y%m%d_%H%M%S') + filename
4. 制作前端html文件
可以去bootstrap官网查找合适的格式并进行修改。