ãã²ã«ã»ã°ãªã³ããŒã°
<<<å æ¬¡>>>
ããã¯ãMega-Tutorial Flaskã·ãªãŒãºã®ç¬¬9çã§ãããŒã¿ããŒã¹å
ã®ãªã¹ããåå²ããæ¹æ³ã説æããŸãã
åèãŸã§ã«ã以äžã¯ãã®ã·ãªãŒãºã®èšäºã®ãªã¹ãã§ãã
泚1ïŒãã®ã³ãŒã¹ã®å€ãããŒãžã§ã³ããæ¢ãã®å Žåã¯ããã¡ããã芧ãã ãã ã
泚2ïŒçªç¶ããã®ããã°ã®ç§ã®ïŒãã²ã«ïŒã®ä»äºãæ¯æããŠå£°ãäžãããå ŽåããŸãã¯åã«èšäºã1é±éåŸ
ã€å¿èããªãå Žåãç§ïŒãã²ã«ã°ãªãŒã³ããŒã°ïŒã¯ãã®ã¬ã€ãã®å®å
šçã«ããã±ãŒãžåãããé»åæžç±ãŸãã¯ãããªãæäŸããŸãã 詳现ã«ã€ããŠã¯ã learn.miguelgrinberg.comãã芧ãã ãã ã
第8ç« ã§ã¯ããœãŒã·ã£ã«ãããã¯ãŒã¯ã§éåžžã«äººæ°ã®ããããã©ãã¯ãŒãïŒãµãã¹ã¯ã©ã€ããŒïŒãã©ãã€ã ããµããŒãããããã«å¿
èŠãªããŒã¿ããŒã¹ã«ããã€ãã®å€æŽãå ããŸããã ãã®æ©èœã«ããããã¢ã³ã¹ãã¬ãŒã·ã§ã³çšã«äœæããæåŸã®ãšã³ããªãåé€ããæºåãã§ããŸããã ãããã¯åœã®ã¡ãã»ãŒãžã§ãã
ãã®ç« ã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯ãŠãŒã¶ãŒããã®ããã°æçš¿ã®åä¿¡ãéå§ããããããã€ã³ããã¯ã¹ããŒãžãšãããã¡ã€ã«ããŒãžã«é
ä¿¡ããŸãã
ãã®ç« ã®GitHubãªã³ã¯ïŒ Browse ã Zip ã Diff ã
ããã°æçš¿
ç°¡åãªãã®ããå§ããŸãããã ããŒã ããŒãžã«ã¯ããŠãŒã¶ãŒãæ°ããã¡ãã»ãŒãžãå
¥åã§ãããã©ãŒã ãå¿
èŠã§ãã æåã«ãã©ãŒã ã¯ã©ã¹ãäœæããŸãã
class PostForm(FlaskForm): post = TextAreaField('Say something', validators=[ DataRequired(), Length(min=1, max=140)]) submit = SubmitField('Submit')
ããã§ããã®ãã©ãŒã ãã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ããŒãžã®ãã³ãã¬ãŒãã«è¿œå ã§ããŸãã
{% extends "base.html" %} {% block content %} <h1>Hi, {{ current_user.username }}!</h1> <form action="" method="post"> {{ form.hidden_tag() }} <p> {{ form.post.label }}<br> {{ form.post(cols=32, rows=4) }}<br> {% for error in form.post.errors %} <span style="color: red;">[{{ error }}]</span> {% endfor %} </p> <p>{{ form.submit() }}</p> </form> {% for post in posts %} <p> {{ post.author.username }} says: <b>{{ post.body }}</b> </p> {% endfor %} {% endblock %}
ãã®ãã³ãã¬ãŒããžã®å€æŽã¯ãä»ã®ãã©ãŒã ã§è¡ããã倿Žã«äŒŒãŠããŸãã çµè«ãšããŠããã©ãŒã ã®äœæãšåŠçã衚瀺æ©èœã«è¿œå ããå¿
èŠããããŸãã
from app.forms import PostForm from app.models import Post @app.route('/', methods=['GET', 'POST']) @app.route('/index', methods=['GET', 'POST']) @login_required def index(): form = PostForm() if form.validate_on_submit(): post = Post(body=form.post.data, author=current_user) db.session.add(post) db.session.commit() flash('Your post is now live!') return redirect(url_for('index')) posts = [ { 'author': {'username': 'John'}, 'body': 'Beautiful day in Portland!' }, { 'author': {'username': 'Susan'}, 'body': 'The Avengers movie was so cool!' } ] return render_template("index.html", title='Home Page', form=form, posts=posts)
ãã®ãã¥ãŒé¢æ°ãžã®å€æŽãé çªã«èŠãŠã¿ãŸãããã
- 远å ãããæ°ããã€ã³ããŒãïŒ
Post
ããã³PostForm
- ãã®ãã¥ãŒé¢æ°ã¯ãã©ãŒã ããŒã¿ãåãåãããã«ãªã£ãããã
GET
èŠæ±ã«å ããŠã index
ããŒãžãã¥ãŒé¢æ°ã«é¢é£ä»ããããäž¡æ¹ã®ã«ãŒãã§ã®POST
èŠæ±ã - ãã©ãŒã åŠçããžãã¯ã¯ãæ°ãã
Post
ãšã³ããªãããŒã¿ããŒã¹ã«è¿œå ããŸãã - ãã³ãã¬ãŒãã¯ãããã¹ããªããžã§ã¯ãã衚瀺ã§ããããã«ããªãã·ã§ã³ã®åŒæ°ãšããŠ
form
ãªããžã§ã¯ããåãåããŸãã
ç¶è¡ããåã«ãWebãã©ãŒã ã®åŠçã«é¢é£ããããã€ãã®éèŠãªãã€ã³ãã«æ³šæãåèµ·ããããšæããŸãã ãã©ãŒã ããŒã¿ãåŠçããåŸã ã€ã³ããã¯ã¹ã®ã¡ã€ã³ããŒãžã«ãªãã€ã¬ã¯ããéä¿¡ããŠãªã¯ãšã¹ããçµäºããããšã«æ³šæããŠãã ããã ããã¯æ¢ã«ã€ã³ããã¯ã¹ãã¥ãŒé¢æ°ã§ããããããªãã€ã¬ã¯ããç°¡åã«ã¹ãããããŠã颿°ããã³ãã¬ãŒãã¬ã³ããªã³ã°ããŒãã§åŒãç¶ãæ©èœãããããšãã§ããŸãã
ãªããªãã€ã¬ã¯ãããã®ã§ããïŒ

æšæºçãªæ¹æ³ã¯ããªãã€ã¬ã¯ããããWebãã©ãŒã ãéä¿¡ãããšãã«POST
èŠæ±ã®èŠæ±ã«å¿çããããšã§ãã ããã¯ãWebãã©ãŠã¶ãŒã§æŽæ°ã³ãã³ãã䜿çšãããšãã«ãåºæ¿ã®çºäœãäœããã®åœ¢ã§åé¿ããã®ã«åœ¹ç«ã¡ãŸãã çµå±ãæŽæ°ãã¿ã³ãã¯ãªãã¯ãããšãWebãã©ãŠã¶ã«æåŸã®ãªã¯ãšã¹ãã衚瀺ãããŸãã ãã©ãŒã éä¿¡ã䌎ãPOST
ãªã¯ãšã¹ããéåžžã®å¿çãè¿ãå ŽåãæŽæ°ã¯ãã©ãŒã ãåéä¿¡ããŸãã ããã¯åžžã«äºæããªãããšã§ããããããã©ãŠã¶ãŒã¯ãŠãŒã¶ãŒã«åéä¿¡ã®ç¢ºèªãæ±ããŸãããã»ãšãã©ã®ãŠãŒã¶ãŒã¯ãã©ãŠã¶ãŒã«å¿
èŠãªãã®ãçè§£ããŸããã
ãããããªãã€ã¬ã¯ããPOST
ãªã¯ãšã¹ãã«å¿çãããšããã©ãŠã¶ã¯GET
ãªã¯ãšã¹ããéä¿¡ããŠãªãã€ã¬ã¯ãã§æå®ãããããŒãžããã£ããã£ããããã«æç€ºããããããæåŸã®ãªã¯ãšã¹ãã¯POSTãªã¯ãšã¹ãã§ã¯ãªããªããæŽæ°ã³ãã³ãã¯ããäºæž¬å¯èœãªæ¹æ³ã§æ©èœããŸãã
ãã®åçŽãªããªãã¯ã¯ã Post / Redirect / Getãã¿ãŒã³ã«ãããŸããã ã ãŠãŒã¶ãŒãWebãã©ãŒã ãéä¿¡ããåŸã«èª€ã£ãŠããŒãžãæŽæ°ãããšãã«ãéè€ããã¡ãã»ãŒãžãæ¿å
¥ãããã®ãé²ããŸãã
ããã°æçš¿ãèŠã
èŠããŠãããªããç§ã¯é·ãéããŒã ããŒãžã«è¡šç€ºããŠããããã€ãã®ããã°æçš¿ãäœæããŸããã ãããã®åœãªããžã§ã¯ãã¯ãåçŽãªPythonãªã¹ããšããŠã€ã³ããã¯ã¹ãã¥ãŒé¢æ°ã§æç€ºçã«äœæãããŸãã
posts = [ { 'author': {'username': 'John'}, 'body': 'Beautiful day in Portland!' }, { 'author': {'username': 'Susan'}, 'body': 'The Avengers movie was so cool!' } ]
ãããä»ãç§ã¯User
ã¢ãã«ã«followed_posts()
ã¡ãœãããããããã®ãŠãŒã¶ãŒãèŠããã¡ãã»ãŒãžãè¿ããŸãã ãã®ãããäžæã¡ãã»ãŒãžãå®éã®ã¡ãã»ãŒãžã«çœ®ãæããããšãã§ããŸãã
@app.route('/', methods=['GET', 'POST']) @app.route('/index', methods=['GET', 'POST']) @login_required def index(): # ... posts = current_user.followed_posts().all() return render_template("index.html", title='Home Page', form=form, posts=posts)
User
ã¯ã©ã¹ã®followed_posts
ã¡ãœããã¯ã User
ãããŒã¿ããŒã¹ãã賌èªããã¡ãã»ãŒãžããã£ããã£ããããã«æ§æãããSQLAlchemyã¯ãšãªãªããžã§ã¯ããè¿ããŸãã ãã®ãªã¯ãšã¹ãã§all()
ãåŒã³åºããšå®è¡ãéå§ãããæ»ãå€ã¯ãã¹ãŠã®çµæãå«ããªã¹ãã«ãªããŸãã
ãããã£ãŠããããŸã§ã«äœ¿çšããäžæã¡ãã»ãŒãžãçæãããã®ãšéåžžã«ããäŒŒãæ§é ãååŸããŸãã ããã¯éåžžã«äŒŒãŠããããããã³ãã¬ãŒãã倿Žããå¿
èŠãããããŸããã
ãŠãŒã¶ãŒæ€çŽ¢ãä¿é²ãã
çŸæç¹ã§ã¢ããªã±ãŒã·ã§ã³ãã©ã®ããã«æ©èœãããã¯ããŠãŒã¶ãŒãä»ã®ãŠãŒã¶ãŒãèŠã€ããããããã«ããã®ã«ããŸã䟿å©ã§ã¯ãªãããšã«æ°ã¥ããããšãé¡ã£ãŠããŸãã å®éãä»ã®ãŠãŒã¶ãŒãäœãããŠããã®ãã確èªããæ¹æ³ã¯ãŸã£ãããããŸããã ããã€ãã®ç°¡åãªå€æŽã§ãããä¿®æ£ããŸãã
æ°ããããŒãžãäœæããå¿
èŠããããŸããããããæ¢çŽ¢ãããŒãžãšåŒã³ãŸãã ãã®ããŒãžã¯ããŒã ããŒãžãšããŠæ©èœããŸãããæ¬¡ã®ãŠãŒã¶ãŒããã®ã¡ãã»ãŒãžã®ã¿ã衚瀺ãã代ããã«ããã¹ãŠã®ãŠãŒã¶ãŒããã®ã°ããŒãã«ãªã¡ãã»ãŒãžãããŒã衚瀺ããŸãã æ°ãããã¥ãŒé¢æ°ã¯æ¬¡ã®ãšããã§ãã
@app.route('/explore') @login_required def explore(): posts = Post.query.order_by(Post.timestamp.desc()).all() return render_template('index.html', title='Explore', posts=posts)
ãã®æ©èœã«å¥åŠãªããšã«æ°ã¥ããããšããããŸããïŒ render_template()
ã®åŒã³åºãã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ããŒãžã§äœ¿çšããindex.htmlãã³ãã¬ãŒããåç
§ããŸãã ãã®ããŒãžã¯ã¡ã€ã³ããŒãžãšéåžžã«äŒŒãŠããããããã³ãã¬ãŒããåå©çšããããšã«ããŸããã
ãã ããã¡ã€ã³ããŒãžãšã®1ã€ã®éãã¯ã[æ¢çŽ¢]ããŒãžã«ã¯ããã°æçš¿ãæžãããã®ãã©ãŒã ãå¿
èŠãªãããããã®ãã¥ãŒé¢æ°ã§ã¯ãã³ãã¬ãŒãåŒã³åºãã«form
åŒæ°ãå«ããªãã£ãããšã§ãã
index.htmlãã³ãã¬ãŒããã¯ã©ãã·ã¥ããªãããã«ãååšããªãWebãã©ãŒã ã衚瀺ããããšãããšãå®çŸ©ãããŠããå Žåã«ã®ã¿ãã©ãŒã ã衚瀺ããæ¡ä»¶ã远å ããŸãã
{% extends "base.html" %} {% block content %} <h1>Hi, {{ current_user.username }}!</h1> {% if form %} <form action="" method="post"> ... </form> {% endif %} ... {% endblock %}
ãŸããããã²ãŒã·ã§ã³ããŒã«ãã®æ°ããããŒãžãžã®ãªã³ã¯ã远å ããŸãã
<a href="{{ url_for('explore') }}">Explore</a>
ãŠãŒã¶ãŒãããã¡ã€ã«ããŒãžã«ããã°æçš¿ã衚瀺ããã«ã¯ã 第6ç« ã®_post.html
ãµããã¿ãŒã³ãèŠããŠããŸããïŒ ããã¯ããŠãŒã¶ãŒãããã¡ã€ã«ããŒãžãã³ãã¬ãŒãããæœåºãããä»ã®ãã³ãã¬ãŒããã䜿çšã§ããããã«åé¢ãããå°ããªãã³ãã¬ãŒãã§ãã ããã°æçš¿ã®ãŠãŒã¶ãŒåããªã³ã¯ãšããŠè¡šç€ºã§ããããã«ãå°ãæ¹åããŸãã
<table> <tr valign="top"> <td><img src="{{ post.author.avatar(36) }}"></td> <td> <a href="{{ url_for('user', username=post.author.username) }}"> {{ post.author.username }} </a> says:<br>{{ post.body }} </td> </tr> </table>
ããã§ããã®ãµããã³ãã¬ãŒãã䜿çšããŠãããŒã ããŒãžã§ããã°ãèŠèŠåããã³åŠç¿ã§ããŸãã
... {% for post in posts %} {% include '_post.html' %} {% endfor %} ...
ãã¹ãããããã³ãã¬ãŒãã¯ã post
ãšããååã®å€æ°ãååšããããšãæ³å®ããŠããããããã€ã³ããã¯ã¹ãã³ãã¬ãŒãå
ã®ã«ãŒã倿°ãåŒã³åºããããããããã¯æ£åžžã«æ©èœããŸãã
ãããã®å°ããªå€æŽã®ãããã§ãã¢ããªã±ãŒã·ã§ã³ã®äœ¿ããããã倧å¹
ã«åäžããŸããã ããã§ããŠãŒã¶ãŒã¯ããŒãžã«ã¢ã¯ã»ã¹ããŠæªç¥ã®ãŠãŒã¶ãŒããã®ããã°æçš¿ãèªãããšãã§ãããããã®æçš¿ã«åºã¥ããŠæ°ãããŠãŒã¶ãŒãèŠã€ããŠãµãã¹ã¯ãªãã·ã§ã³ã远å ã§ããŸãã ãããã
ãã®æç¹ã§ãã¢ããªã±ãŒã·ã§ã³ãå詊è¡ããŠããããã®ææ°ã®UIã®æ¹åãäœéšããããšããå§ãããŸãã

ããã°æçš¿ã®å
±æ
ã¢ããªã±ãŒã·ã§ã³ã¯ä»¥åãããèŠæ ãããããªããŸãããããŒã ããŒãžã«ãã¹ãŠã®ãšã³ããªã衚瀺ããããšã¯ãæ³åãããã¯ããã«æ©ãåé¡ã«ãªããŸãã ãŠãŒã¶ãŒã1,000ä»¶ã®ã¬ã³ãŒããæã£ãŠããå Žåã¯ã©ããªããŸããïŒ ãããšã100äžïŒ ãã®ãããªå€§éã®ã¡ãã»ãŒãžã®ãªã¹ãã®ç®¡çã¯ãéåžžã«é
ããéå¹ççã§ãã
ãã®åé¡ã解決ããããã«ãã¡ãã»ãŒãžã®ãªã¹ããåå²ããŸãã ã€ãŸããæåã¯äžåºŠã«éãããæ°ã®ã¡ãã»ãŒãžã®ã¿ã衚瀺ããã¡ãã»ãŒãžãªã¹ãã®æ®ãã®éšåãããã²ãŒããããªã³ã¯ãå«ããŸãã Flask-SQLAlchemyã¯ã paginate()
ã¯ãšãªã¡ãœããã䜿çšããŠãã€ãã£ãã«ããŒãžããŒã·ã§ã³ããµããŒãããŸãã ããšãã°ãæåã®20åã®ãŠãŒã¶ãŒã¬ã³ãŒããååŸããå¿
èŠãããå Žåããªã¯ãšã¹ãã®æåŸã«all()
ãžã®åŒã³åºãã眮ãæããããšãã§ããŸãã
>>> user.followed_posts().paginate(1, 20, False).items
paginate
ã¡ãœããã¯ãFlask-SQLAlchemyã®ä»»æã®ã¯ãšãªãªããžã§ã¯ãã«å¯ŸããŠåŒã³åºãããšãã§ããŸãã ããã«ã¯3ã€ã®åŒæ°ãå¿
èŠã§ãã
- 1ããå§ãŸãããŒãžçªå·
- ããŒãžãããã®èŠçŽ æ°
- ãšã©ãŒãã©ã°ã
True
å Žåãç¯å²å€ã®ããŒãžãèŠæ±ããããšã404ãšã©ãŒãèªåçã«ã¯ã©ã€ã¢ã³ãã«è¿ãããŸãã False
å Žåãç¯å²å€ã®ããŒãžã«å¯ŸããŠç©ºã®ãªã¹ããè¿ãããŸãã
paginate
ããã®æ»ãå€ã¯ã Pagination
ãªããžã§ã¯ãã§ãã ãã®ãªããžã§ã¯ãã®items
屿§ã«ã¯ããªã¯ãšã¹ããããããŒãžã®ã¢ã€ãã ã®ãªã¹ããå«ãŸããŠããŸãã Paginationãªããžã§ã¯ãã«ã¯ãŸã æçšãªãã®ããããŸãããããã«ã€ããŠã¯åŸã§èª¬æããŸãã
次ã«ã index()
ãã¥ãŒé¢æ°ã§ããŒãžããŒã·ã§ã³ãå®è£
ããæ¹æ³ã«ã€ããŠèããŠã¿ãŸãããã ãŸããããŒãžã«è¡šç€ºãããã¢ã€ãã ã®æ°ã決å®ããæ§æã¢ã€ãã ãã¢ããªã±ãŒã·ã§ã³ã«è¿œå ããŸãã
class Config(object): # ... POSTS_PER_PAGE = 3
ã¢ããªã±ãŒã·ã§ã³å
šäœã®ãããã®ãããããæ§æãã¡ã€ã«ã®åäœã«åœ±é¿ãäžããå¯èœæ§ãããããšããå§ãããŸããããã«ããã1ãæã§ãã¹ãŠã®ä¿®æ£ãè¡ãããšãã§ããŸãã ãã®çµæãç§ã¯ãã¡ãããããŒãžäžã§3ã€ä»¥äžã®èŠçŽ ã䜿çšããŸããããã¹ãã«ã¯å°ããªæ°ã§äœæ¥ããã®ã䟿å©ã§ãã
次ã«ãããŒãžçªå·ãã¢ããªã±ãŒã·ã§ã³URLã«å«ããæ¹æ³ã決å®ããå¿
èŠããããŸãã ããªãäžè¬çãªæ¹æ³ã¯ã ã¯ãšãªæåååŒæ°ã䜿çšããŠãªãã·ã§ã³ã®ããŒãžçªå·ãæå®ããããšã§ããæå®ãããŠããªãå Žåã¯ãããã©ã«ãã§ããŒãž1ã«è¡šç€ºãããŸãã ãããå®è£
ããæ¹æ³ã瀺ãURLã®äŸã次ã«ç€ºããŸãã
ã¯ãšãªæååã§æå®ãããåŒæ°ã«ã¢ã¯ã»ã¹ããã«ã¯ãFlaskãªããžã§ã¯ãã®request.args
ãªããžã§ã¯ãã䜿çšã§ããŸãã ããã«ã€ããŠã¯ã 第5ç« ã§ãã§ã«èª¬æããŸãããããã§ã¯ãFlask-Loginããã®ãŠãŒã¶ãŒãã°ã€ã³çšã®URLãå®è£
ããŸããã
次ã®äŸã¯ãããŒã ããŒãžã®å
èš³ãããã€ãã«è¿œå ãã衚瀺æ©èœã調æ»ããæ¹æ³ã瀺ããŠããŸãã
@app.route('/', methods=['GET', 'POST']) @app.route('/index', methods=['GET', 'POST']) @login_required def index(): # ... page = request.args.get('page', 1, type=int) posts = current_user.followed_posts().paginate( page, app.config['POSTS_PER_PAGE'], False) return render_template('index.html', title='Home', form=form, posts=posts.items) @app.route('/explore') @login_required def explore(): page = request.args.get('page', 1, type=int) posts = Post.query.order_by(Post.timestamp.desc()).paginate( page, app.config['POSTS_PER_PAGE'], False) return render_template("index.html", title='Explore', posts=posts.items)
ãããã®å€æŽã§ã¯ã2ã€ã®ã«ãŒãã®äž¡æ¹ãã page
ãªã¯ãšã¹ãã®page
åŒæ°ããããŸãã¯ããã©ã«ãã§1ã®ããããã§ã衚瀺ããããŒãžçªå·ã決å®ããŸããæ¬¡ã«ã paginate()
ã¡ãœããã䜿çšããŠãçµæã®ç®çã®ããŒãžã®ã¿ãååŸããŸãã ããŒãžãµã€ãºã決å®ããPOSTS_PER_PAGE
æ§æPOSTS_PER_PAGE
ã POSTS_PER_PAGE
ãªããžã§ã¯ãããã¢ã¯ã»ã¹ã§ããŸãã
ãããã®å€æŽãã©ãã»ã©ç°¡åã§ãã©ã®ã³ãŒãã«ãã»ãšãã©åœ±é¿ããªãããšã«æ³šæããŠãã ããã ç§ã¯åéšåãæžããä»ã®éšåã®äœæ¥ããæœè±¡åããããšããŠããŸããããã«ãããæ¡åŒµãšãã¹ãã容æãªã¢ãžã¥ãŒã«åŒã§ä¿¡é Œæ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸãã åæã«ãèŽåœçãªãã¹ãå°ããªãã¹ãçºçããå¯èœæ§ã¯æ¬è³ªçã«å°ããã§ãã
ç¶ããŠïŒ ãããŠãããŒãžããŒã·ã§ã³æ©èœã詊ããŠã¿ãã¹ãã§ãã äºåã«3ã€ä»¥äžã®ããã°æçš¿ãããããšã確èªããŠãã ããã ããã¯ããã¹ãŠã®ãŠãŒã¶ãŒããã®ã¡ãã»ãŒãžã衚瀺ãããæ€çŽ¢ããŒãžã§èŠããããªããŸãã ããã§ãæåŸã®3ã€ã®ã¡ãã»ãŒãžã®ã¿ã衚瀺ã§ããŸãã æ¬¡ã®3ã€ã衚瀺ããå Žåã¯ã http://localhost:5000/explore?page=2
ããã©ãŠã¶ãŒã®ã¢ãã¬ã¹ããŒã«å
¥åããŸãã
ããŒãžããã²ãŒã·ã§ã³
次ã®å€æŽç¹ã¯ãããã°æçš¿ã®ãªã¹ãã®äžéšã«ãªã³ã¯ã远å ããŠããŠãŒã¶ãŒã次ã®ããŒãžãåã®ããŒãžã«ç§»åã§ããããã«ããããšã§ãã paginate()
åŒã³åºãããã®æ»ãå€ã¯ãFlask-SQLAlchemyããã®Paginationã¯ã©ã¹ã®ãªããžã§ã¯ãã§ããããšãè¿°ã¹ãããšãæãåºããŠãã ããã ãããŸã§ããã®ãªããžã§ã¯ãã®items屿§ã䜿çšããŸãããã
éžæããããŒãžã«ã€ããŠååŸãããã¢ã€ãã ã®ãªã¹ããå«ãŸããŸãã ãããããã®ãªããžã§ã¯ãã«ã¯ãããŒãžãžã®ãªã³ã¯ãäœæãããšãã«åœ¹ç«ã€ããã€ãã®ä»ã®å±æ§ããããŸãã
- has_nextïŒçŸåšã®ããŒãžã®åŸã«å°ãªããšã1ã€ã®ããŒãžãããå Žåã¯true
- has_prevïŒçŸåšã®ããŒãžã®åã«å¥ã®ããŒãžãããå Žåã¯true
- next_numïŒæ¬¡ã®ããŒãžã®ããŒãžçªå·
- prev_numïŒåã®ããŒãžã®ããŒãžçªå·
ããã4ã€ã®èŠçŽ ã䜿çšããŠãããŒãžïŒæ¬¡ããã³åïŒãžã®ãªã³ã¯ãäœæãããããã衚瀺çšã®ãã³ãã¬ãŒãã«æž¡ãããšãã§ããŸãã
@app.route('/', methods=['GET', 'POST']) @app.route('/index', methods=['GET', 'POST']) @login_required def index(): # ... page = request.args.get('page', 1, type=int) posts = current_user.followed_posts().paginate( page, app.config['POSTS_PER_PAGE'], False) next_url = url_for('index', page=posts.next_num) \ if posts.has_next else None prev_url = url_for('index', page=posts.prev_num) \ if posts.has_prev else None return render_template('index.html', title='Home', form=form, posts=posts.items, next_url=next_url, prev_url=prev_url) @app.route('/explore') @login_required def explore(): page = request.args.get('page', 1, type=int) posts = Post.query.order_by(Post.timestamp.desc()).paginate( page, app.config['POSTS_PER_PAGE'], False) next_url = url_for('explore', page=posts.next_num) \ if posts.has_next else None prev_url = url_for('explore', page=posts.prev_num) \ if posts.has_prev else None return render_template("index.html", title='Explore', posts=posts.items, next_url=next_url, prev_url=prev_url)
ããã2ã€ã®é¢æ°ã®next_url
ããã³prev_url
ã¯ããã®æ¹åã«ããŒãžãããå Žåã«ã®ã¿ã url_for()
ã«ãã£ãŠè¿ãããURLã䜿çšããŸãã çŸåšã®ããŒãžãã¡ãã»ãŒãžã³ã¬ã¯ã·ã§ã³ã®äžæ¹ã®ç«¯ã«ããå Žåã has_next
ãªããžã§ã¯ãã®has_next
ãŸãã¯has_prev
屿§ã¯False
ã«ãªããŸãããã®å Žåããã®æ¹åã®ãªã³ã¯ã¯None
ã«èšå®ãããŸãã
åã«çç¥ããurl_for()
颿°ã®è峿·±ãåŽé¢ã®1ã€ã¯ãããŒã¯ãŒãåŒæ°ã远å ã§ããããšã§ãããããã®åŒæ°ã®ååãURLã§çŽæ¥æå®ãããŠããªãå ŽåãFlaskã¯ããããURLã«å«ããŸãèŠæ±åŒæ°ãšããŠã®ã¢ãã¬ã¹ã
ããŒãžãžã®ãªã³ã¯ã¯index.htmlãã³ãã¬ãŒãã§èšå®ãããŠããã®ã§ãæçš¿ã®ãªã¹ãã®ããäžã®ããŒãžã«ãªã³ã¯ã衚瀺ããŸãããã
... {% for post in posts %} {% include '_post.html' %} {% endfor %} {% if prev_url %} <a href="{{ prev_url }}">Newer posts</a> {% endif %} {% if next_url %} <a href="{{ next_url }}">Older posts</a> {% endif %} ...
ãã®ã¢ããªã³ã¯ãã€ã³ããã¯ã¹ã®ã¡ã€ã³ããŒãžãšèª¿æ»äžã®ããŒãžã®äž¡æ¹ã®æçš¿ã®ãªã¹ãã®äžã«ãªã³ã¯ã远å ããŸãã æåã®ãªã³ã¯ã¯ãæ°ããæçš¿ããšããŠããŒã¯ãããåã®ããŒãžãæããŸãïŒææ°ã®ããŒã¿ã§ãœãŒããããã¡ãã»ãŒãžã衚瀺ããŠãããããæåã®ããŒãžã¯ææ°ã®ã³ã³ãã³ãã§ãïŒã
2çªç®ã®ãªã³ã¯ã¯ãå€ãæçš¿ããšããŠããŒã¯ãããæçš¿ã®æ¬¡ã®ããŒãžãæããŸãã
ããã2ã€ã®ãªã³ã¯ã®ãããããNone
å Žåããªã³ã¯ã¯æ¡ä»¶åŒãä»ããŠããŒãžã«è¡šç€ºãããŸããã

ãŠãŒã¶ãŒãããã¡ã€ã«ããŒãžã®æ¹ããŒãž
çŸåšãã€ã³ããã¯ã¹ããŒãžã«ååãªå€æŽããããŸãã ãã ãããŠãŒã¶ãŒãããã¡ã€ã«ããŒãžã«ã¯ããããã¡ã€ã«ææè
ããã®ã¡ãã»ãŒãžã®ã¿ã衚瀺ããã¡ãã»ãŒãžã®ãªã¹ããå«ããå¿
èŠããããŸãã äžè²«æ§ãä¿ã€ã«ã¯ããŠãŒã¶ãŒãããã¡ã€ã«ããŒãžãã€ã³ããã¯ã¹ããŒãžãšåæ§ã«å€æŽããå¿
èŠããããŸãã
äžæã¡ãã»ãŒãžã®ãªã¹ãããŸã ãããŠãŒã¶ãŒãããã¡ã€ã«ãã¥ãŒæ©èœãæŽæ°ããããšããå§ããŸãã
@app.route('/user/<username>') @login_required def user(username): user = User.query.filter_by(username=username).first_or_404() page = request.args.get('page', 1, type=int) posts = user.posts.order_by(Post.timestamp.desc()).paginate( page, app.config['POSTS_PER_PAGE'], False) next_url = url_for('user', username=user.username, page=posts.next_num) \ if posts.has_next else None prev_url = url_for('user', username=user.username, page=posts.prev_num) \ if posts.has_prev else None return render_template('user.html', user=user, posts=posts.items, next_url=next_url, prev_url=prev_url)
ãŠãŒã¶ãŒããã¡ãã»ãŒãžã®ãªã¹ããååŸããã«ã¯ã user.posts
é¢ä¿ãããŠãŒã¶ãŒã¢ãã«ã®db.relationship()
å®çŸ©ã®çµæãšããŠSQLAlchemyãæ¢ã«æ§æããã¯ãšãªã§ãããšããäºå®ã䜿çšããŸãã ãã®ã¯ãšãªã䜿çšãã order_by()
ã远å ããŠææ°ã®æçš¿ãæåã«ååŸããŠãããindexããã³exploreã®æçš¿ãšãŸã£ããåãããŒãžåå²ãè¡ããŸãã url_for()
ã«ãã£ãŠçæãããããŒãžãžã®ãªã³ã¯ã¯ãURLã®åçã³ã³ããŒãã³ããšããŠãã®ãŠãŒã¶ãŒåãæã€ãŠãŒã¶ãŒãããã¡ã€ã«ããŒãžãæãããã远å ã®username
åŒæ°ãå¿
èŠã§ããããšã«æ³šæããŠãã ããã
çµè«ãšããŠã user.htmlãã³ãã¬ãŒããžã®å€æŽã¯ãã€ã³ããã¯ã¹ããŒãžã§è¡ã£ã倿Žãšåãã§ãã
... {% for post in posts %} {% include '_post.html' %} {% endfor %} {% if prev_url %} <a href="{{ prev_url }}">Newer posts</a> {% endif %} {% if next_url %} <a href="{{ next_url }}">Older posts</a> {% endif %}
ããŒãžããŒã·ã§ã³æ©èœã®å®éšãçµäºããããæ§æPOSTS_PER_PAGE
ããé©åãªå€ã«èšå®ã§ããŸãã
class Config(object): # ... POSTS_PER_PAGE = 25
<<<å æ¬¡>>>