18.上傳文件限制和使用富文本編輯器【完結篇】

本文是後端開發——Flask初體驗專欄的最後一篇文章,整個Q&A demo的簡單框架其實已經創建起來了,如今就是再優化、完善一些細節。
本文首先完善一下前文上傳頭像的部分,增長上傳文件的大小和格式限制,其次把發佈問答部分中,問題的詳細描述部分從普通的textarea修改成富文本編輯器TinyMCE,這樣能夠在問題描述中添加各類格式的信息,如代碼、表格、列表、圖片等。
最後,整個demo已經上傳到GitHub:QADemoByFlask,歡迎你們訪問、關注和交流。javascript


首先在config.py中添加css

MAX_CONTENT_LENGTH = 1 * 1024 * 1024

表示最大上傳文件的限制是1MB,添加完成便可,Flask會自動處理,若是上傳的文件超出,會拋出異常,顯示沒法鏈接,但程序不會中斷;其次在exts.py中添加函數:html

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in ['jpg', 'jpeg', 'png', 'gif']

咱們用這個來確保用戶上傳的文件是指定的4種擴展名的格式。再從werkzeug庫中導出
secure_filename來檢驗文件名的安全性,這一步也是十分必要的,具體緣由可參考Flask文檔。此時視圖函數修改以下:java

@app.route('/user/avatar/', methods=['GET', 'POST'])
def avatar():
    if request.method == 'POST':
        file = request.files['avatar_upload']
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            base_path = path.abspath(path.dirname(__file__))
            filename = str(g.user.id) + '.' + filename.rsplit('.', 1)[1]
            file_path = path.join(base_path, 'static', 'images', 'uploads', filename)
            file.save(file_path)
            g.user.avatar_path = 'images/uploads/' + filename
            db.session.commit()
    return render_template('avatar.html')

如今網上有許多富文本編輯器可供咱們使用,這裏選擇TinyMCE,詳情和文檔能夠瀏覽其官網。首先須要引用tinymce.min.js這個文件,就像是用Bootstrap同樣,咱們能夠直接在線引用,但會有個討厭的提示,以下圖:git

clipboard.png

所以我直接將其下載(開發版下載)到本地,解壓至項目的static文件夾,同時下載漢化文件zh_CN.js,放入langs文件夾,文件夾結構以下:github

clipboard.png

而後在static/javascript文件夾中新建一個tinymce_setup.js文件,用於配置TinyMCE,其內容以下:數據庫

tinymce.init({
    selector: '#tinymce-content',
    language:'zh_CN',
    height:200,
    plugins: [
            'advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker',
            'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking',
            'save table contextmenu directionality emoticons template paste textcolor',
            'codesample',
    ],
     toolbar: 'insertfile undo redo | \
     styleselect | \
     bold italic | \
     alignleft aligncenter alignright alignjustify | \
     bullist numlist outdent indent | \
     link image | \
     print preview media fullpage | \
     forecolor backcolor emoticons |\
     codesample fontsizeselect fullscreen',
     nonbreaking_force_tab: true,
});

代碼中selector其實就是css中的選擇器,會把對應的html元素替換成TinyMCE富文本編輯器,pluginstoolbar是設定編輯器帶有哪些功能和按鈕。此時能夠在question.html中引入TinyMCEjs和配置文件的js,以下:flask

<script src="{{ url_for('static', filename='tinymce/js/tinymce/tinymce.js') }}"></script>
<script src="{{ url_for('static', filename='javascript/tinymce_setup.js') }}"></script>

其實還須要引入jQuery,但咱們以前在引入Bootstrap的時候,在base.html中已經引入了,而question.html又繼承自base.html。將question.html中的segmentfault

<div class="form-group">
    <textarea class="form-control" rows="6" placeholder="問題描述" name="question_desc"></textarea>
</div>

替換爲後端

<div class="tinymce-group">
    <textarea id="tinymce-content" name="question_desc"></textarea>
</div>

此時再點擊發布問答進入頁面,已經可使用TinyMCE了,以下:

clipboard.png

隨便插入張圖片,點擊提交試試,發現後端獲取到的數據是帶html標記的文本,數據庫數據以下:

clipboard.png

detail.html中的內容也是這樣的字符串:

clipboard.png

如何把這樣的內容渲染成html呢?其實很簡單,給html中的參數加個safe過濾器就能夠了:

{{ question.content | safe }}

此時detail.html中的圖片就正常顯示了:

clipboard.png

相關文章
相關標籤/搜索