Flask博客開發——自定義頭像

Flask Web開發一書中,使用了與我的郵箱綁定的Gravatar圖形做爲用戶頭像。Gravatar提供的頭像比較簡陋,並且可能因爲網絡問題沒法生成頭像。多數社交網站和博客提供用戶自定義頭像功能,所以本身加上了自定義頭像的功能。html

思路:用戶選擇我的頭像後,將頭像文件上傳到服務器端特定的文件夾中;在用戶模型中添加字段,保存頭像存儲的路徑,這樣就實現了頭像與用戶的關聯。前端

 

一、模型中添加頭像路徑字段bootstrap

保留原有的avatar_hash字段,定義real_avatar字段用來存儲頭像地址。服務器

# models.py
class User(UserMixin, db.Model):
    # ...
    real_avatar = db.Column(db.String(128), default = None) 

 

二、上傳文件表單網絡

使用FileField類建立了上傳文件的表單字段。網上也有人把頭像修改和編輯我的資料集成到一個表單裏,但一般來講用戶資料修改和頭像修改是獨立的功能,並且資料修改有用戶和管理員兩個級別,集成到一塊對程序修改較多。session

# main/forms.py
class ChangeAvatarForm(FlaskForm):
    avatar = FileField('')
    submit = SubmitField('Submit')

 

 三、修改頭像的視圖函數app

提交上傳文件的表單後,可經過request.files字典中得到上傳的文件對象,該對象的filename屬性爲文件名,從文件名中可提取後綴名,判斷上傳的文件是不是容許的格式。確認格式無誤後,將文件保存到upload_folder文件夾中,文件名爲「用戶名+後綴名」,因爲每一個用戶的用戶名不一樣,所以可使用便於識別的用戶名來命名頭像,也可使用用戶id命名頭像文件。函數

# main/views.py
@main.route('/change-avatar', methods=['GET', 'POST'])
@login_required
def change_avatar():
    '''修改頭像'''
    form = ChangeAvatarForm()
    if form.validate_on_submit():
        # 文件對象
        avatar = request.files['avatar']
        fname = avatar.filename     
        # 存儲路徑 
        upload_folder = current_app.config['UPLOAD_FOLDER']      
        # 容許格式
        allowed_extensions = ['png', 'jpg', 'jpeg', 'gif']      
        # 後綴名
        fext = fname.rsplit('.',1)[-1] if '.' in fname else ''
        # 判斷是否符合要求
        if fext not in allowed_extensions:   
            flash('File error.')
            return redirect(url_for('.user', username=current_user.username))
        # 路徑+用戶名+後綴名
        target = '{}{}.{}'.format(upload_folder, current_user.username, fext)
        avatar.save(target)
        current_user.real_avatar = '/static/avatars/{}.{}'.format(current_user.username, fext)
        db.session.add(current_user)
        flash('Your avatar has been updated.')
        return redirect(url_for('.user', username = current_user.username))
    return render_template('change_avatar.html', form=form)

 配置文件中配置頭像文件保存路徑:測試

# config.py
class Config:
    UPLOAD_FOLDER = os.getcwd() + '/app/static/avatars/'

 

 四、前端的修改網站

在change_avatar.html頁面渲染ChangeAvatarForm表單:

<!-- templates/change_avatar.html -->
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}Flasky - Change Avatar{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Change Your Avatar</h1>
</div>
<div class="col-md-4">
    {{ wtf.quick_form(form) }}
</div>
{% endblock %}

在我的用戶頁面,可直接使用頭像圖片做爲連接,地址是頭像上傳頁面。因爲用戶資料頁面是開放的,只有用戶本人或管理員訪問時才加上此連接。同時爲了和原有的Gravatar頭像功能兼容,這裏進行了判斷:當用戶上傳了本身的頭像時,顯示自定義頭像,不然顯示默認的Gravatar頭像。同時,還將自定義頭像的尺寸與Gravatar頭像的尺寸保持一致,顯得更協調些。也能夠不用Gravatar頭像,像多數網站同樣設置一個默認的頭像。

除了用戶頁面外,帳戶、博客文章、評論這幾處也會用到小頭像,要予以修改,保持一致。

     <!-- templates/user.html -->
     <a {% if user == current_user or current_user.is_administrator() %}href="{{ url_for('.change_avatar') }}"{% endif %}>
    {% if user.real_avatar %}
    <img class="img-rounded profile-thumbnail" src="{{ user.real_avatar }}" height="256" width="256" >
    {% else %}
    <img class="img-rounded profile-thumbnail" src="{{ user.gravatar(size=256) }}">
    {% endif %}
    </a>    

 

五、測試

完成以上代碼後,修改頭像後的我的頁面顯示效果以下:

點擊大頭像便可進入上傳頭像頁面。目前用戶提供的頭像須要自行截切成正方形,不然頭像會壓扁或拉長,很難看。通常的社交網站的頭像修改界面每每提供圖像的預覽和截切功能,主要和前端相關,後續也可將該部分功能集成到程序裏。

 

 

 

 

 

 

 

 

能夠多測試幾個用戶:

相關文章
相關標籤/搜索