記錄一次完整的flask小型應用開發(3)
阿新 • • 發佈:2018-12-18
接下來,我們開始實現使用者資料頁面,即每個使用者可以展示給其他人的個人個性介面
為了讓個人資訊介面看起來更加的充實,我們對User模型新增幾個欄位來記錄更多的使用者資訊:
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模型中定義這個方法:
def ping(self):
self.last_seen = datetime.utcnow()
db.session.add(self)
接下來需要在每次使用者提交請求的時候呼叫這個方法即可,想起之前定義的auth藍本中有一個before_app_request會在每次請求前執行,所以我們可以在這個處理程式裡面呼叫這個方法:
@auth.before_app_request def before_request(): if current_user.is_authenticated: current_user.ping() if not current_user.confirmed \ and request.endpoint \ and request.blueprint != 'auth' \ and request.endpoint != 'static': return redirect(url_for('auth.unconfirmed'))
使用者資料頁面
現在我們充實了使用者的各種資訊,所以我們現在可以開始定製個人的使用者資料頁面了。
首先我們定義路由,因為不是認證功能了,所以不要在auth裡面實現了,可以在main裡面實現:
# 為每個使用者定義個人資料頁面路由 @main.route('/user/<username>') def user(username): user = User.query.filter_by(username=username).first() # 在資料庫中搜索URL指定的使用者名稱 if user is None: abort(404) return render_template('user.html', user=user)
老樣子,實現了路由功能,我們還需要模板來展示:
{% extends "base.html" %}
{% block title %}Flasky - {{ user.username }}{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>{{ user.username }}</h1>
{% if user.name or user.location %}
<p>
{% if user.name %}{{ user.name }}{% endif %}
{% if user.location %}
from <a href="http://maps.google.com/?q={{ user.location }}">{{ user.location }}</a>
{% 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).fromNow() }}.</p>
<p>
{% if user == current_user %}
<a class="btn btn-default" href="{{ url_for('.edit_profile') }}">Edit Profile</a>
{% endif %}
{% if current_user.is_administrator() %}
<a class="btn btn-danger" href="{{ url_for('.edit_profile_admin', id=user.id) }}">Edit Profile [Admin]</a>
{% endif %}
</p>
</div>
{% endblock %}
這裡如果使用者是管理員,那麼就顯示使用者的電子郵箱,並且渲染成mailto連結,現在我們還想使用者可以在頁面上方的導航欄裡面直接看到profile選項,點進去可以看到使用者的個人資料,那麼,我們在base.html裡面加上:
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('main.user', username=current_user.username) }}">Profile</a></li>
{% endif %}
使用者資料編輯
首先建立普通使用者級別的資料編輯器:
class EditProfileForm(FlaskForm):
# 普通使用者級別的資料編輯表單
name = StringField('Real name', validators=[Length(0, 64)])
location = StringField('Location', validators=[Length(0, 64)])
about_me = TextAreaField('About me')
submit = SubmitField('Submit')
然後定義這個路由:
@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.about_me = 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)
這裡實現了功能,我們需要這個編輯資料頁面的渲染模板:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky - Edit Profile{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Edit Your Profile</h1>
</div>
<div class="col-md-4">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
現在還缺少的是使用者從哪裡可以點選進入編輯資料頁面,我們直接在profile頁面定義一個入口:
{% if user == current_user %}
<a class="btn btn-default" href="{{ url_for('.edit_profile') }}">Edit Profile</a>
{% endif %}
檢查一下功能是沒問題的~!!!
設定使用者頭像
最後我們設定一下使用者的頭像,用於美化頁面。
我們使用Gravatar提供的使用者頭像功能,它能將頭像和電子郵件關聯起來,我們將構建頭像URL的方法寫入User模型中
def gravatar(self, size=100, default='identicon', rating='g'):
url = 'https://secure.gravatar.com/avatar'
hash = hashlib.md5(self.email.lower().encode('utf-8')).hexdigest()
return '{url}/{hash}?s={size}&d={default}&r={rating}'.format(
url=url, hash=hash, size=size, default=default, rating=rating)
然後我們將這個頭像顯示到個人資料頁面中:
<img class="img-rounded profile-thumbnail" src="{{ user.gravatar(size=256) }}">
好了,現在頁面中就能顯示圖片了!!!