[python3.6 flask web学习]Flask用户资料管理

每个注册用户都需要有一个专门的个人资料页面,实现个性化信息管理。

用户资料这个功能模块主要分为两个部分,资料的展示和编辑。

1.资料的展示

目前User模型字段太少,新增添加location(地址),about_me(个人描述),member_since(注册时间),last_seen(最后访问时间)。修改app/model.py 里的User类

class User(UserMixin, db.Model):
    #...
    name = db.Column(db.String(64))
    location = db.Column(db.String(64))
    about_me = db.Column(db.Text())
    member_since = db.Column(db.DateTime(), default = datetime.utcnow)
    last_seen = db.Column(db.DateTime(), default = datetime.utcnow)

last_seen字段每次用户访问的时候会更新,因此,在User中新增更新方法

class User(UserMixin, db.Model):
    #...
    def ping(self):
        self.last_seen = datetime.utcnow
        db.session.add(self)

由于每次请求都需要更新last_seen字段,因此在蓝本auth中的before_app_request中调用该方法。修改app/auth/views.py

@auth.before_app_request
def before_request():
    if current_user.is_authenticated():
        current_user.ping()
        if not current_user.confirmed \
              and request.endpoint[:5] != 'auth'
              return redirect(url_for('auth.unconfirmed'))

完成了用户访问时间的更新之后,下面实现用户的资料展示页面。用户的资料展示页面路由形式/user/username

@main.route('/user/<username>')
def user(username):
    user = User.query.filter_by(username=username).first()
    if user is None:
        abort(404)
    return render_template('user.html'.user=user)


用户更资料页面模板app/templates/user.html

{% block page_content %}
<div class="page-header">
	<h1>{{ user.username }}</h1>
	{% if user.username or user.location %}
	<p>
		{% if user.name %}{{ user.name }}{% endif%}
		{% if user.location %}
			From {{ user.location }}
		{% endif %}
	</p>
	{% endif %}
	{% if current_user.is_administrator() %}
	<p><a href="mailto:{{ user.email }}">{{ user.email }}</a></p>
	{% endif %}
	{% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
	<p>
		member since {{ moment(user.member_since).format('L') }}
		last seen {{ moment(user.last_seen).format('L') }}
	</p>
</div>
{% endblock %}

在导航栏新增个人资料栏,修改base.html

{% if current_user.is_authenticated() %}
<li>
	<a  href="{{ url_for('main.user', username=current_user.username) }}">
		Profile
	</a>
</li>
{% endif %}

2.普通用户资料编辑

之所以分为普通用户资料编辑和管理员用户资料编辑这两个页面,是因为普通用户只能编辑自己资料,而管理员则可以编辑所有人资料,并且管理员还可以设置用户的角色权限更信息。

app/main/forms.py:资料编辑表单

class EditProfileForm(Form):
	name = StringField('Real name', validators=[Length(0, 64)])
	location = StringField('Location', validators=[Length(0, 64)])
	about_me = TextAreaField('About me')
	submit = SubmitField('Submit')

修改app/main/views.py,新增普通用户资料编辑路由

@main.route('/edit-profile', methods=['GET', 'POST'])
@login_required
def edit_profile():
	form = EditProfileForm()
	if form.validate_on_submit():
		current_user.name = form.name.data
		current_user.location = form.location.data
		current_user.7= form.about_me.data
		db.session.add(current_user)
		flash('Your profile has been updated.')
		return redirect(url_for('.user', username=current_user.username))
	
	form.name.data = current_user.name
	form.location.data = current_user.location
	form.about_me.data = current_user.about_me
	return render_template('edit_profile.html', form=form)

同时在用户资料页面新增编辑资料按钮 app/templates/user.html

{% if user == current_user %}
<a class="btn btn-default" href="{{ url_for('.edit_profile') }}">
Edit Profile
</a>
{% endif %}

3.管理员编辑资料页面

管理员在表单能编辑用户的电子邮件、用户名、确认状态和角色。新增管理员使用的资料编辑表单,修改app/main/forms.py

class EditProfileAdminForm(Form):
	email = StringField('Email', validators=[Required(), Length(1, 64),
	Email()])
	username = StringField('Username', validators=[
	Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
	'Usernames must have only letters, '
	'numbers, dots or underscores')])
	confirmed = BooleanField('Confirmed') #单选框
	role = SelectField('Role', coerce=int) #下拉选项
	name = StringField('Real name', validators=[Length(0, 64)])
	location = StringField('Location', validators=[Length(0, 64)])
	about_me = TextAreaField('About me')
	submit = SubmitField('Submit')

def __init__(self, user, *args, **kwargs):
	super(EditProfileAdminForm, self).__init__(*args, **kwargs)
	self.role.choices = [(role.id, role.name)
	for role in Role.query.order_by(Role.name).all()] #设置choices值即设置下拉选项列表
		self.user = user
	
def validate_email(self, field):
	if field.data != self.user.email and \
		User.query.filter_by(email=field.data).first():#表单数据变化了且数据在数据库不存在
		raise ValidationError('Email already registered.')
	
def validate_username(self, field):
	if field.data != self.user.username and \
		User.query.filter_by(username=field.data).first():
		raise ValidationError('Username already in use.')

管理员的资料编辑路由 app/main/views.py

@main.route('/edit-profile/<int:id>', methods=['GET', 'POST'])
@login_required
@admin_required
def edit_profile_admin(id):
	user = User.query.get_or_404(id)
	form = EditProfileAdminForm(user=user)
	if form.validate_on_submit():
		user.email = form.email.data
		user.username = form.username.data
		user.confirmed = form.confirmed.data
		user.role = Role.query.get(form.role.data)
		user.name = form.name.data
		user.location = form.location.data
		user.about_me = form.about_me.data
		db.session.add(user)
		flash('The profile has been updated.')
		return redirect(url_for('.user', username=user.username))
	form.email.data = user.email
	form.username.data = user.username
	form.confirmed.data = user.confirmed
	form.role.data = user.role_id
	form.name.data = user.name
	form.location.data = user.location
	form.about_me.data = user.about_me
	return render_template('edit_profile.html', form=form, user=user)

4.用户头像

Gravatar 是一个行业领先的头像服务,能把头像和电子邮件地址关联起来。用户先要到http://gravatar.com 中注册账户,然后上传图片。生成头像的URL 时,要计算电子邮件地址的MD5 散列值。

(venv) $ python
>>> import hashlib
>>> hashlib.md5('john@example.com'.encode('utf-8')).hexdigest()
'd4c74594d841139328695756648b6bd6'


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值