说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!
接着上一篇博客继续往下写 :Flask项目之个性化微电影网站的实战开发(三)_cdtaogang's blog-优快云博客
目录
一丶前台管理(会员模块)
1.会员注册
- 定义会员注册表单
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[345789]\\d{9}", 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("手机号码已经存在!")
- 填写模板数据
<form novalidate role="form" method="post">
<fieldset>
<div class="form-group">
<label for="input_name"><span class="glyphicon glyphicon-user"></span> {
{form.name.label}}</label>
{
{form.name}}
{% for error in form.name.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_name"></div>
<div class="form-group">
<label for="input_email"><span class="glyphicon glyphicon-envelope"></span> {
{form.email.label}}</label>
{
{form.email}}
{% for error in form.email.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_email"></div>
<div class="form-group">
<label for="input_phone"><span class="glyphicon glyphicon-phone"></span> {
{form.phone.label}}</label>
{
{form.phone}}
{% for error in form.phone.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_phone"></div>
<div class="form-group">
<label for="input_password"><span class="glyphicon glyphicon-lock"></span> {
{form.pwd.label}}</label>
{
{form.pwd}}
{% for error in form.pwd.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_password"></div>
<div class="form-group">
<label for="input_repassword"><span class="glyphicon glyphicon-lock"></span> {
{form.repwd.label}}</label>
{
{form.repwd}}
{% for error in form.repwd.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_repassword"></div>
{
{form.submit}}
{
{form.csrf_token}}
</fieldset>
</form>
- 定义视图函数
# 会员注册
@home.route('/register/', methods=['GET', 'POST'])
def register():
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/register.html",form=form)
- 测试会员注册功能
2.会员登录以及退出
会员登录
- 定义登录表单
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",
}
)
- 定义登录视图函数
# 会员登录
@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 not user.check_pwd(data['pwd']):
flash("密码错误!", "err")
return redirect(url_for('home.login'))
# 将登录成功后的用户名以及用户id保存到session会话机制中
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)
- 填写模板数据
<form novalidate role="form" method="post">
<fieldset>
<div class="form-group">
<label for="input_contact"><span class="glyphicon glyphicon-user"></span> {
{form.name.label}}</label>
{
{form.name}}
{% for error in form.name.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_contact"></div>
<div class="form-group">
<label for="input_password"><span class="glyphicon glyphicon-lock"></span> {
{form.pwd.label}}</label>
{
{form.pwd}}
{% for error in form.pwd.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_password"></div>
{
{form.submit}}
{
{form.csrf_token}}
</fieldset>
</form>a
- 测试会员登录功能
会员退出
- 定义退出视图函数
# 会员退出
@home.route('/logout/')
def logout():
session.pop("user", None)
session.pop("user_id", None)
return redirect(url_for("home.login"))
- 定义登录装饰器
# 登录装饰器
def user_login_required(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
- 测试会员退出功能以及访问需要登录后才能访问的页面
3.修改会员资料
显示会员信息
- 定义会员信息表单
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[345789]\\d{9}", 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",
}
)
- 定义视图函数
# 会员详情
@home.route('/user/', methods=['GET', 'POST'])
@user_login_required
def user():
form = UserdetailForm()
form.face.validators = [] # 默认图片为空
user = User.query.get(int(session['user_id']))
# 设置表单字段初始值
if request.method == 'GET':
form.name.data = user.name
form.email.data = user.email
form.phone.data = user.phone
form.face.data = user.face
form.info.data = user.info
if form.validate_on_submit():
data = form.data
return render_template("home/user.html", form=form, user=user)
- 填写模板数据
<form novalidate role="form" method="post" enctype="multipart/form-data">
<fieldset>
<div class="form-group">
<label for="input_name"><span class="glyphicon glyphicon-user"></span> {
{form.name.label}}</label>
{
{form.name}}
{% for error in form.name.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_name"></div>
<div class="form-group">
<label for="input_email"><span class="glyphicon glyphicon-envelope"></span> {
{form.email.label}}</label>
{
{form.email}}
{% for error in form.email.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<div class="col-md-12" id="error_email"></div>
<div class="form-group">
<label for="input_phone"><span class="glyphicon glyphicon-phone"></span> {
{form.phone.label}}</label>
{
{form.phone}}
{% for error in form.phone.errors %}
<div class="col-md-12">
<p style="color:red">{
{ error }}</p>
</div>
{% endfor %}
</div>
<d