flask_分頁

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 %}
相關文章
相關標籤/搜索