# Python Flask實作_開始建置頁面內容_11_blog_post_加入編輯功能 ###### tags: `python` `flask` `blog` ## 說明 寫作編輯是難免,在處理SelectField的default時,需特別注意到型別問題,我們所設置的id是int,而SelectField預設卻是string,這會造成無法設置data或是default,其餘的部份大同小異, ## 作業說明 首先我們設置一個View Function,這個部份主要是讓編輯文章使用,可是這個編輯文章所用的form跟我們在建置文件的form是一樣的,需求的html格式也一樣,我們需要的就只是讓資料庫目前存在的這筆資料提取出來之後渲染在這個form與html上。 :::success * 文件:app_blog\blog\view.py * 說明:設置一個編輯文章使用的View Function ```python= @blog.route('/blog_post/u/<int:post_id>/', methods=['GET', 'POST']) @login_required def update_blog_post(post_id): """ 更新post :param post_id: :return: """ post = Blog_Post.query.filter_by(id=post_id).first_or_404() form = Form_Blog_Post() if form.validate_on_submit(): post.title = form.post_title.data post.body = form.post_body.data print(form.post_body.data) post.blog_main_id = form.post_blog.data post.category_id = form.post_category.data db.session.add(post) db.session.commit() flash('Edit Your Post Success') return redirect(url_for('blog.read_blog_post', slug=post.slug)) form.post_title.data = post.title form.post_body.data = post.body form.post_blog.data = post.blog_main_id form.post_category.data = post.category_id # 利用參數action來做條件,判斷目前是新增還是編輯 return render_template('blog/blog_post_edit.html', form=form, post=post, action='edit') ``` 第9行:取得該筆post_id的資料 第26行:利用參數action來判斷目前是編輯還是新增 ::: 接著我們調整一下文章呈現的部份,加入判斷式,如果文章的作者與目前登入人員相等,就顯示edit的超連結 :::success * 文件:templates\blog\blog_post_read.html * 說明:加入條件判斷作者是否與目前登入人員相同。 ```htmlmixed= {% extends "base.html" %} {% block title %}{{ post.title }}{% endblock %} {% block page_content %} <div class="page-header"> <h2>Post</h2> </div> <div> <h3>{{ post.title }}</h3> <!-- 加入判斷作者與目前登入人員是否相同,若是則顯示 --> {% if post.author_id == current_user.id %} <div class="post-editor"> <a href="{{ url_for('blog.update_blog_post', post_id = post.id) }}">Edit</a> </div> {% endif %} <!-- 下略 --> ``` ::: 調整blog_post_edit.html這個版面,加入判斷action來決定顯示的字段。 :::success * 文件:templates\blog\blog_post_edit.html * 說明:加入判斷action ```htmlmixed= {% extends "base.html" %} {% import "bootstrap/wtf.html" as wtf %} {% block title %}Blog_Post_Edit{% endblock %} {% block page_content %} <div class="page-header"> <h1>Hello, {{ current_user.username }}</h1> <!-- 加入判斷action,如果是edit就顯示edit your post --> {% if action=='edit' %} <h2>Edit Your Post</h2> {% else %} <h2>Write Your Story</h2> {% endif %} </div> <div class="col-md-4"> {{ wtf.quick_form(form) }} </div> {% endblock %} ``` ::: :::warning * 測試 * 說明:確認編修狀況 ![](https://i.imgur.com/vbCJQYw.png) 點擊edit之後確實的引導到編輯的畫面,畫面的顯示也是Edit。 ![](https://i.imgur.com/UYzmBnu.png) ::: ## 總結 要特別注意的就是開頭說的部份,在規劃Form的時候SelectField必需設置參數『coerce=int』,否則會發現在這邊取出model資料之後怎麼指定data都是失敗的。 完成了編輯功能,整個模型已經大致完成了,最後,為了執行上的效能,我們必需避免整個文章list一次性的將所有資料導出,這需要加入分頁,sqlalchemy已經幫我們設想好了,下一節我們一起來看怎麼加入分頁功能。 ## 其它 在wtform的官方文件中有提到,我們提取了model物件之後,可以在實作form的時候利用obj這個參數來做渲染,只要你的form底下的filed物件與model內的column名稱設置相同,那就會自動的渲染。 :::success * 文件:app_blog\blog\form.py * 說明:假設form的filed名稱與model的屬性名稱相同,我們可以直接利用obj渲染,而不用一個一個指定設置 ```python= @blog.route('/blog_post/u/<int:post_id>/', methods=['GET', 'POST']) @login_required def update_blog_post(post_id): """ 更新post :param post_id: :return: """ post = Blog_Post.query.filter_by(id=post_id).first_or_404() form = Form_Blog_Post(obj=post) if form.validate_on_submit(): form.populate_obj(post) db.session.commit() ``` :::