1、提交博客文章html
1.定義一個單字段的表單對象(form.py)數據庫
1 class PostForm(Form): 2 post = StringField('post', validators=[DataRequired()])
2.把表單添加到模板中:(templates/user.html)瀏覽器
1 {% extends "base.html" %} 2 {% block content %} 3 <h1>Hi, {{user.nickname}}!</h1> 4 <form action="" method="post" name="post"> 5 {{form.hidden_tag()}} 6 <table> 7 <tr> 8 <td>Say something:</td> 9 <td>{{ form.post(size = 30, maxlength = 140) }}</td> 10 <td> 11 {% for error in form.errors.post %} 12 <span style="color: red;">[{{error}}]</span><br> 13 {% endfor %} 14 </td> 15 </tr> 16 <tr> 17 <td></td> 18 <td><input type="submit" value="Post!"></td> 19 <td></td> 20 </tr> 21 </table> 22 </form> 23 {% for post in posts %} 24 {% include 'post.html' %} 25 {% endfor %}
3.利用視圖函數來處理表單session
1 from form import LoginForm,EditForm,PostForm 2 @app.route('/') 3 @login_required 4 def index(): 5 user=g.user 6 form=PostForm() 7 from model import Post 8 from model import db 9 if form.validate_on_submit(): 10 post=Post(body=form.post.data,timestamp=datetime.utcnow(),user_id=user.id) 11 db.session.add(post) 12 db.session.commit() 13 flash('Your post is now live!') 14 return redirect(url_for('index')) 15 posts=user.followed_posts() 16 print "posts:",posts 17 return render_template('index.html',title='home',form=form,user=user,posts=posts)
注:這裏咱們解釋一下爲何要重定向到首頁(index)app
若是一個用戶正在撰寫 blog,接着不當心按到了瀏覽器的刷新鍵,會發生些什麼。刷新的命令將會作些什麼?瀏覽器將會從新發送上一次的請求做爲刷新命令的結果。沒有重定向,上一次的請求是提交表單的 POST 請求,所以刷新動做將會從新提交表單,致使與第一個相同的第二個 Post 記錄被寫入數據庫。這並很差。有了重定向,咱們迫使瀏覽器在表單提交後發送另一個請求,即重定向頁的請求。這是一個簡單的 GET 請求,所以一個刷新動做將會重複 GET 請求而不是屢次提交表單。函數
2、分頁post
Flask-SQLAlchemy 天生就支持分頁。好比說咱們想要在第一頁顯示前三條blog,咱們能夠這麼作:ui
posts=user.followed_posts().paginate(1, 3, False).itemsurl
paginate 方法可以被任何查詢調用。它接受三個參數:spa
1.頁數,從1開始
2.每一頁顯示的blog數目
3.錯誤標誌。若是是 True,當請求的範圍頁超出範圍的話,一個 404 錯誤將會自動地返回到客戶端的網頁瀏覽器。若是是 False,返回一個空列表而不是錯誤。
從 paginate 返回的值是一個 Pagination 對象。這個對象的 items 成員包含了請求頁面項目(本文是指 blog)的列表。在 Pagination 對象中還有其它有幫助的東西,咱們將在後面能看到。
如今讓咱們想一想如何在咱們的 index 視圖函數中實現分頁。咱們首先在配置文件中添加一些決定每頁顯示的 blog 數的配置項(文件 config.py):
# 每頁顯示的blog數
POSTS_PER_PAGE = 3
接着,讓咱們看看不一樣頁的 URLs 是什麼樣的。咱們知道 Flask 路由能夠攜帶參數,所以咱們在 URL 後添加一個後綴表示所需的頁面:
http://localhost:5000/ <-- page #1 (default) http://localhost:5000/index <-- page #1 (default) http://localhost:5000/index/1 <-- page #1 http://localhost:5000/index/2 <-- page #2
這種格式的 URLs 可以輕易地經過在咱們的視圖函數中附加一個 route 來實現(文件microblog.py):
1 @app.route('/index<int:page>',methods=['GET','POST']) 2 @login_required 3 def index(page=1): 4 user=g.user 5 form=PostForm() 6 from model import Post 7 from model import db 8 if form.validate_on_submit(): 9 post=Post(body=form.post.data,timestamp=datetime.utcnow(),user_id=user.id) 10 db.session.add(post) 11 db.session.commit() 12 flash('Your post is now live!') 13 return redirect(url_for('index')) 14 posts=user.followed_posts().paginate(page,POSTS_PER_PAGE,False).items 15 # print "posts:",posts 16 return render_template('index.html',title='home',form=form,user=user,posts=posts)
咱們新的路由須要頁面數做爲參數,而且聲明爲一個整型。一樣咱們也須要在 index 函數中添加 page 參數,而且咱們須要給它一個默認值。
如今咱們已經有可用的頁面數,咱們可以很容易地把它與配置中的 POSTS_PER_PAGE 一塊兒傳入 followed_posts 查詢。
如今試試輸入不一樣的 URLs,看看分頁的效果。可是,須要確保可用的 blog 數要超過三個,這樣你就可以看到不止一頁了!
4.在頁面中添加導航(index.html)
在咱們目前的版本中咱們按以下方式使用 paginate 方法:
posts=user.followed_posts().paginate(page,POSTS_PER_PAGE,False).items
經過上面這樣作,咱們能夠得到返回自 paginate 的 Pagination 對象的 items 成員。可是這個對象還有不少其它有用的東西在裏面,所以咱們仍是使用整個對象(文件microblog.py):
posts=user.followed_posts().paginate(page,POSTS_PER_PAGE,False)
修改模板index.html
這個改變使得模版可以使用徹底的 Paginate 對象。咱們使用的這個對象的成員有:
(1)has_next:若是在目前頁後至少還有一頁的話,返回 True
(2)has_prev:若是在目前頁以前至少還有一頁的話,返回 True
(3)next_num:下一頁的頁面數
(4)prev_num:前一頁的頁面數
有了這些元素後,咱們產生了這些(文件 app/templates/index.html):
1 {% for post in posts.items %} 2 {% include 'post.html' %} 3 {% endfor %} 4 {% if posts.has_prev %}<a href="{{ url_for('index', page = posts.prev_num) }}"><< Newer posts</a>{% else %}<< Newer posts{% endif %} | 5 {% if posts.has_next %}<a href="{{ url_for('index', page = posts.next_num) }}">Older posts >></a>{% else %}Older posts >>{% endif %} 6 {% endblock %}
所以,咱們有了兩個連接。第一個就是名爲 「Newer posts」,這個連接使得咱們可以訪問上一頁。第二個就是 「Older posts」,它指向下一頁。
3、修改用戶信息頁
(1)microblog.py
1 @app.route('/user/<nickname>') 2 @app.route('/user/<nickname>/<int:page>') 3 @login_required 4 def user(nickname,page=1): 5 user =model.User.query.filter_by(nickname = nickname).first() 6 posts=user.posts.paginate(page,POSTS_PER_PAGE,False) 7 if user == None: 8 flash('User ' + nickname + ' not found.') 9 return redirect(url_for('index')) 10 return render_template('user.html', 11 user = user, 12 posts = posts)
(2)user.html
1 {% for post in posts.items %} 2 {% include 'post.html' %} 3 {% endfor %} 4 {% if posts.has_prev %}<a href="{{ url_for('user', nickname = user.nickname, page = posts.prev_num) }}"><< Newer posts</a>{% else %}<< Newer posts{% endif %} | 5 {% if posts.has_next %}<a href="{{ url_for('user', nickname = user.nickname, page = posts.next_num) }}">Older posts >></a>{% else %}Older posts >>{% endif %}