ããã¯ãFlaskãã€ã¯ããã¬ãŒã ã¯ãŒã¯ã䜿çšããŠPython Webã¢ããªã±ãŒã·ã§ã³ãäœæããçµéšã説æããã·ãªãŒãºã®9çªç®ã®èšäºã§ãã
ãã®ã¬ã€ãã®ç®çã¯ãéåžžã«æ©èœçãªãã€ã¯ãããã°ã¢ããªã±ãŒã·ã§ã³ãéçºããããšã§ã
microblog.
ãªãªãžããªãã£ãå®å
šã«æ¬ åŠããŠããããšãã
microblog.
ãšåŒã¶ããšã«ããŸãã
microblog.
çãç¹°ãè¿ã
åã®èšäºã§ã¯ããŠãŒã¶ãŒãä»ã®ãŠãŒã¶ãŒã®æçš¿ã远跡ã§ããããµãã¹ã¯ã©ã€ããŒããã©ãã€ã ããµããŒãããããã«ãããŒã¿ããŒã¹ã«å¿
èŠãªãã¹ãŠã®å€æŽãå ããŸããã
ä»æ¥ã¯ãååè¡ã£ãããšã«åºã¥ããŠãã¢ããªã±ãŒã·ã§ã³ã念é ã«çœ®ããŠããŠãŒã¶ãŒã«å®éã®ã³ã³ãã³ããåãåã£ãŠé
ä¿¡ããããã«ããŸãã ä»æ¥ãç§ãã¡ã¯æåŸã®åœç©ã«å¥ããåããŸãïŒ
ããã°æçš¿ã®éä¿¡
ç°¡åãªãã®ããå§ããŸãããã ããŒã ããŒãžã«ã¯ãæ°ããæçš¿çšã®ã«ã¹ã¿ã ãã©ãŒã ãå¿
èŠã§ãã
æåã«ãåäžãã£ãŒã«ãã®ãã©ãŒã ãªããžã§ã¯ã
( app/forms.py)
ãå®çŸ©ããŸãã
class PostForm(Form): post = TextField('post', validators = [Required()])
次ã«ããã©ãŒã ããã³ãã¬ãŒã
( app/templates/index.html)
è¿œå ã
( app/templates/index.html)
ïŒ
<!-- extend base layout --> {% extends "base.html" %} {% block content %} <h1>Hi, {{g.user.nickname}}!</h1> <form action="" method="post" name="post"> {{form.hidden_tag()}} <table> <tr> <td>Say something:</td> <td>{{ form.post(size = 30, maxlength = 140) }}</td> <td> {% for error in form.errors.post %} <span style="color: red;">[{{error}}]</span><br> {% endfor %} </td> </tr> <tr> <td></td> <td><input type="submit" value="Post!"></td> <td></td> </tr> </table> </form> {% for post in posts %} <p> {{post.author.nickname}} says: <b>{{post.body}}</b> </p> {% endfor %} {% endblock %}
ãæ°ã¥ããããããŸããããè¶
èªç¶çãªãã®ã¯ãããŸããã 以åãšåãããã«ãå¥ã®å³åœ¢ãè¿œå ããŸãã
ãããŠæåŸã«ããã¹ãŠãçµã³ä»ãããã¥ãŒé¢æ°
( app/views.py)
ïŒ
from forms import LoginForm, EditForm, PostForm from models import User, ROLE_USER, ROLE_ADMIN, 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, timestamp = datetime.utcnow(), author = g.user) db.session.add(post) db.session.commit() flash('Your post is now live!') return redirect(url_for('index')) posts = [ { 'author': { 'nickname': 'John' }, 'body': 'Beautiful day in Portland!' }, { 'author': { 'nickname': 'Susan' }, 'body': 'The Avengers movie was so cool!' } ] return render_template('index.html', title = 'Home', form = form, posts = posts)
ãã®é¢æ°ã§è¡ã£ãå€æŽãã¹ãããããšã«èŠãŠã¿ãŸãããã
- ãŸãã
Post
ã¯ã©ã¹ãšPostForm
ã¯ã©ã¹ãã€ã³ããŒãããŸãPostForm
index()
ãã¥ãŒé¢æ°ã«é¢é£ä»ããããäž¡æ¹ã®ã«ãŒãããã®POSTãªã¯ãšã¹ããåãå
¥ããŸããããã§ã¯æ°ããæçš¿ãåãå
¥ããŸãã
- æçš¿ãããŒã¿ããŒã¹ã«ä¿åãããåã«ããã®é¢æ°ã«åé¡ãããŸãã GETãä»ããŠãã®é¢æ°ã«å
¥ããšããã¹ãŠã以åã®ããã«è¡ãããŸãã
- ãã³ãã¬ãŒãã¯ãããã¹ããã£ãŒã«ãã«ã¬ã³ããªã³ã°ãããã©ãŒã ãšããè¿œå ã®åŒæ°ãåãåããŸãã
ãããŠæåŸã«ãç¶è¡ããåã«ã æ°ããæçš¿ãããŒã¿ããŒã¹ã«æžã蟌ãåã«ããããè¡ãããšã«æ³šæããŠãã ããã
return redirect(url_for('index'))
ãã®ãªãã€ã¬ã¯ããç°¡åã«ã¹ãããããŠãã¬ã³ããªã³ã°ã«é²ãããšãã§ããŸãã ããããããã¯ããã«å¹æçã§ãã å®éããã®ãªãã€ã¬ã¯ããè¡ãããšã¯ãã¹ãŠãå®éã«ãã®æ©èœã«æ»ãããã§ãã
ã§ã¯ããªããªãã€ã¬ã¯ããªã®ã§ããããïŒ ãŠãŒã¶ãŒãããã°ã«æçš¿ãæžã蟌ã¿ãå
¬éããæŽæ°ãã¿ã³ãæŒãããšãã«äœãèµ·ããããèããŠãã ããã æŽæ°ã³ãã³ãã¯äœãããŸããïŒ ãã©ãŠã¶ã¯ä»¥åã®ãªã¯ãšã¹ããåéä¿¡ããŸãã
ãªãã€ã¬ã¯ãããªãå ŽåãæåŸã®1ã€ã¯ãã©ãŒã ãéä¿¡ããPOSTãªã¯ãšã¹ãã§ãã£ãããããæŽæ°ãã¢ã¯ã·ã§ã³ã¯ãã®ãªã¯ãšã¹ããåéä¿¡ããæåã®ãã¹ããšåã2çªç®ã®ãã¹ããäœæããŸãã ããã¯æªãã§ãã
ãã ãããªãã€ã¬ã¯ãã䜿çšãããšããã©ãŒã ã®éä¿¡åŸã«ãã©ãŠã¶ãŒã«å¥ã®èŠæ±ã匷å¶çã«çºè¡ãããŸãã ããã¯åçŽãªGETãªã¯ãšã¹ãã§ãããRefreshãã¿ã³ã¯ãã©ãŒã ãå床éä¿¡ãã代ããã«ãããŒãžãå床ããŒãããã ãã§ãã
ãã®åçŽãªããªãã¯ã«ããããŠãŒã¶ãŒãæçš¿åŸã«èª€ã£ãŠããŒãžãæŽæ°ããå Žåã«ãéè€ããæçš¿ãæ¿å
¥ããªãããã«ããããšãã§ããŸãã
ããã°æçš¿ã衚瀺ãã
æãèå³æ·±ããã®ã«æž¡ããŸãã ããŒã¿ããŒã¹ããæçš¿ãåŒãåºããŠè¡šç€ºããŸãã
ããã€ãã®èšäºãæãåºããŠããã ããã°ãåœã®æçš¿ãããã€ãäœæããé·ãéã¡ã€ã³ããŒãžã«è¡šç€ºããŠããŸããã ãããã®åœãªããžã§ã¯ãã¯ãPythonãªã¹ããã¥ãŒé¢æ°ã§æ瀺çã«äœæãããŸããã
posts = [ { 'author': { 'nickname': 'John' }, 'body': 'Beautiful day in Portland!' }, { 'author': { 'nickname': 'Susan' }, 'body': 'The Avengers movie was so cool!' } ]
ããããååã®èšäºã§ã¯ããŠãŒã¶ãŒããµãã¹ã¯ã©ã€ãããŠãããŠãŒã¶ãŒããã®ãã¹ãŠã®ã¡ãã»ãŒãžãåä¿¡ã§ããããã«ãããªã¯ãšã¹ããäœæãããããäžèšã®è¡
( app/views.py)
ç°¡åã«çœ®ãæããããšãã§ã
( app/views.py)
ã
posts = g.user.followed_posts().all()
ããã§ãã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãããŒã¿ããŒã¹ããã®æçš¿ã衚瀺ãããŸãïŒ
User
ã¯ã©ã¹ã®
followed_post
ã¡ãœããã¯ãé¢å¿ã®ããã¡ãã»ãŒãžãååŸããããã«æ§æãããsqlalchemy
query
ãªããžã§ã¯ããè¿ããŸãã ãã®ãªããžã§ã¯ãã§
all()
ã¡ãœãããåŒã³åºããšã
all()
ã®æçš¿ãã·ãŒãã®åœ¢åŒã§ååŸããããããæçµçã«ã¯äœ¿ãæ
£ããæ§é ã§äœæ¥ã§ããŸãã ãããã¯éåžžã«é¡äŒŒããŠããããããã³ãã¬ãŒãã¯äœãèªèããŸããã
ããã§ãã¢ããªã±ãŒã·ã§ã³ã§éã¶ããšãã§ããŸãã æ¥ããããããªãã§ãã ããã è€æ°ã®ãŠãŒã¶ãŒãäœæããããããä»ã®ãŠãŒã¶ãŒã«ãµãã¹ã¯ã©ã€ãããæåŸã«è€æ°ã®ã¡ãã»ãŒãžãå
¬éããŠãåãŠãŒã¶ãŒãèªåã®ãã£ãŒããã©ã®ããã«è¡šç€ºãããã確èªã§ããŸãã
ããŒãžããŒã·ã§ã³
ç§ãã¡ã®ã¢ããªã±ãŒã·ã§ã³ã¯ãããŸã§ä»¥äžã«è¯ãèŠããŸãããåé¡ããããŸãã ããŒã ããŒãžã«ãã¹ãŠã®ã¡ãã»ãŒãžã衚瀺ããŸãã ãŠãŒã¶ãŒãæ°å人ã«ãµã€ã³ã¢ãããããšã©ããªããŸããïŒ ãããšã100äžïŒ ãæ³åã®ãšããããã®ãããªå€§ããªãªã¹ããååŸããŠåŠçããããšã¯éåžžã«éå¹ççã§ãã
代ããã«ãæœåšçã«å€æ°ã®ããŒãžåå²ãããæçš¿ã衚瀺ããŸãã
Flask-SQLAlchemyã«ã¯ãéåžžã«åªããããŒãžããŒã·ã§ã³ãµããŒããåãã£ãŠããŸãã ããšãã°ã远跡察象ãŠãŒã¶ãŒããæåã®3ã€ã®æçš¿ãååŸãããå Žåã¯ã次ã®ããã«ããŸãã
posts = g.user.followed_posts().paginate(1, 3, False).items
paginate
ã¡ãœãã
paginate
ã
query
ãªããžã§ã¯ãã§åŒã³åºãããŸãã 次ã®3ã€ã®åŒæ°ãå¿
èŠã§ãã
- 1ããå§ãŸãããŒãžçªå·
- ããŒãžãããã®èŠçŽ æ°ã
- ããã³ãšã©ãŒãã©ã°ã ãã©ã°ãTrueã«èšå®ãããŠããå Žåããªã¹ããè¶
ãããšã404ãšã©ãŒãã¯ã©ã€ã¢ã³ãã«è¿ãããŸãã
- ãã以å€ã®å Žåã¯ããšã©ãŒã®ä»£ããã«ç©ºã®ãªã¹ããè¿ãããŸãã
paginate
ã¡ãœããã¯ãããŒãžããŒã·ã§ã³ãªããžã§ã¯ããè¿ããŸãã ãã®ãªããžã§ã¯ãã®ã¡ã³ããŒã«ã¯ãèŠæ±ãããããŒãžã®èŠçŽ ã®ãªã¹ããå«ãŸããŠããŸãã Paginationãªããžã§ã¯ãã«ã¯ä»ã«ã䟿å©ãªãã®ããããŸããããããã«ã€ããŠã¯åŸã»ã©èª¬æããŸãã
indexïŒïŒãã¥ãŒé¢æ°ã§ããŒãžããŒã·ã§ã³ãå®è£
ããæ¹æ³ã«ã€ããŠèããŠã¿ãŸãããã ãŸããã¢ããªã±ãŒã·ã§ã³ã«æ§æèŠçŽ ãè¿œå ããŠãããŒãžã«è¡šç€ºããèŠçŽ ã®æ°ã決å®ããŸãã
åäœã«åœ±é¿ãäžããå¯èœæ§ãããã°ããŒãã«ã¢ããªã±ãŒã·ã§ã³èšå®ã1ãæã«ä¿åããããšããå§ãããŸãã
ãã¡ãããæçµã¢ããªã±ãŒã·ã§ã³ã§ã¯3ãã倧ããæ°ã䜿çšããŸããããã¹ãã«ã¯å°éã§äœæ¥ããæ¹ã䟿å©ã§ãã
次ã«ãããŒãžãªã¯ãšã¹ããå«ãURLãã©ã®ããã«ãªããã決ããŸãããã Flaskã䜿çšãããšãã«ãŒãã§åŒæ°ãåãå
¥ããããšãã§ãããããç®çã®ããŒãžãæããµãã£ãã¯ã¹ãè¿œå ã§ããŸãã
http://localhost:5000/ <-- page
ãã®URL圢åŒã¯ããã¥ãŒ
( app/views.py)
è¿œå ã«ãŒãã䜿çšããŠç°¡åã«å®è£
ã§ããŸãã
from config import POSTS_PER_PAGE @app.route('/', methods = ['GET', 'POST']) @app.route('/index', methods = ['GET', 'POST']) @app.route('/index/<int:page>', methods = ['GET', 'POST']) @login_required def index(page = 1): form = PostForm() if form.validate_on_submit(): post = Post(body = form.post.data, timestamp = datetime.utcnow(), author = g.user) db.session.add(post) db.session.commit() flash('Your post is now live!') return redirect(url_for('index')) posts = g.user.followed_posts().paginate(page, POSTS_PER_PAGE, False).items return render_template('index.html', title = 'Home', form = form, posts = posts)
æ°ããã«ãŒãã¯ãåŒæ°ãããŒãžçªå·ã§ã€ã³ã¯ããæŽæ°ãšããŠå®£èšããŸãã ãŸãããã®åŒæ°ã
index()
é¢æ°ã«è¿œå ããŠããã©ã«ãå€ãèšå®ããå¿
èŠããããŸããããã¯ã3ã€ã®ã«ãŒãã®ãã¡2ã€ããã®åŒæ°ã䜿çšãããããã©ã«ãå€ã§äœ¿çšãããããã§ãã
ããŒãžçªå·ãã§ããã®ã§ãåã«å®çŸ©ãã
POSTS_PER_PAGE
å€æ°ãšãšãã«ã
followed_posts
ãªã¯ãšã¹ãã«ç°¡åã«æ¥ç¶ã§ããŸãã
ãããã®å€æŽãããã«ç°¡åã§ãã³ãŒãã®å€æŽãå°ãªãããšã«æ³šç®ããŠãã ããã ä»ã®éšåãã©ã®ããã«æ©èœããããæšæž¬ããã®ã§ã¯ãªããã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®éšåãèšè¿°ããããšããŸããããã«ããããã¹ãããããã¢ãžã¥ãŒã«åŒã§ä¿¡é Œæ§ã®é«ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã
ãã©ãŠã¶ã®ã¢ãã¬ã¹ããŒã«ç°ãªãè¡çªå·ã®URLãå
¥åããããšã§ãããŒãžããŒã·ã§ã³ãäœéšã§ããããã«ãªããŸããã ããŒãžã«è¡šç€ºãããæçš¿ã3ã€ä»¥äžããããšã確èªããŠãã ããã
ããŒãžããã²ãŒã·ã§ã³
次ã«ããŠãŒã¶ãŒã次/åã®ããŒãžã«ç§»åã§ãããªã³ã¯ãè¿œå ããå¿
èŠããããŸãã幞ããªããšã«ãFlask-SQLAlchemyãã»ãšãã©ã®äœæ¥ãè¡ããŸãã
ãã¬ãŒã³ããŒã·ã§ã³æ©èœã«å°ããªå€æŽãå ããããšããå§ããŸãã çŸåšã®ããŒãžã§ã³ã§ã¯ã次ã®ããã«ããŒãžããŒã·ã§ã³ã䜿çšããŠããŸãã
posts = g.user.followed_posts().paginate(page, POSTS_PER_PAGE, False).items
ããã«ãããpaginateã¡ãœããã«ãã£ãŠè¿ãããPaginationãªããžã§ã¯ãã®èŠçŽ ã®ã¿ãä¿åããŸãã ãã ãããã®ãªããžã§ã¯ãã¯éåžžã«äŸ¿å©ãªæ©èœãæäŸããããããªããžã§ã¯ãå
šäœ
( app/views.py)
ã
posts = g.user.followed_posts().paginate(page, POSTS_PER_PAGE, False)
ãã®å€æŽãã³ããŒããã«ã¯ããã³ãã¬ãŒã
( app/templates/index.html)
ãå€æŽããå¿
èŠããã
( app/templates/index.html)
ïŒ
<!-- posts is a Paginate object --> {% for post in posts.items %} <p> {{post.author.nickname}} says: <b>{{post.body}}</b> </p> {% endfor %}
ãã³ãã¬ãŒãã®Paginateãªããžã§ã¯ããæäŸãããã®ã 䜿çšãããªããžã§ã¯ãã®ã¡ãœããã¯æ¬¡ã®ãšããã§ãã
- has_nextïŒçŸåšã®ããŒãžã®åŸã«å°ãªããšã1ããŒãžãããŸã
- has_prevïŒçŸåšã®åã«å°ãªããšã1ããŒãžãããå Žåã¯true
- next_numïŒæ¬¡ã®ããŒãžçªå·
- prev_numïŒåã®ããŒãžçªå·
圌ãã®å©ããåããŠã次ã®ããšãã§ããŸã
( app/templates/index.html)
ïŒ
<!-- posts is a Paginate object --> {% for post in posts.items %} <p> {{post.author.nickname}} says: <b>{{post.body}}</b> </p> {% endfor %} {% if posts.has_prev %}<a href="{{ url_for('index', page = posts.prev_num) }}"><< Newer posts</a>{% else %}<< Newer posts{% endif %} | {% if posts.has_next %}<a href="{{ url_for('index', page = posts.next_num) }}">Older posts >></a>{% else %}Older posts >>{% endif %}
ããã§2ã€ã®ãªã³ã¯ãã§ããŸããã æåã«ããæ°ããæçš¿ããªã³ã¯ã衚瀺ããŸããããã«ãããåã®ããŒãžããæ°ããæçš¿ã«ç§»åã§ããŸãã äžæ¹ãå€ãæçš¿ã¯æ¬¡ã®ããŒãžãå€ãæçš¿ã«éãããŸãã
ããããæåã®ããŒãžã«ãããšãã¯ãåã®ããŒãžãžã®ãªã³ã¯ã¯å¿
èŠãããŸããã ãã®ãããªå Žåã¯ãfalseãè¿ãposts.has_prevã¡ãœããã䜿çšããŠç°¡åã«è¿œè·¡ã§ããŸãã ãã®å Žåããªã³ã¯ããã¹ãã¯è¡šç€ºãããŸããããªã³ã¯èªäœã¯è¡šç€ºãããŸããã 次ã®ããŒãžã§ã¯ãªããªã³ã¯ãåæ§ã«åŠçãããŸãã
ãµããã¿ãŒã³ã®å®è£
åŸ
åã«ãã¢ãã¿ãŒãè¿œå ããèšäºã§ã1ã€ã®æçš¿ãã¬ã³ããªã³ã°ããããã®HTMLã³ãŒãã§ãµããã¿ãŒã³ãå®çŸ©ããŸãã ç°ãªãããŒãžã«æçš¿ã衚瀺ãããå Žåã«ã³ãŒãã®éè€ããªããããã«ããã®ãã³ãã¬ãŒããäœæããŸããã
ã¡ã€ã³ããŒãžã«ãã®ãµããã¿ãŒã³ãå®è£
ããæãæ¥ãŸããããä»æ¥ã®ã»ãšãã©ã®ããš
( app/templates/index.html)
ãšåããããç°¡å
( app/templates/index.html)
ïŒ
<!-- posts is a Paginate object --> {% for post in posts.items %} {% include 'post.html' %} {% endfor %}
ãããã å€ãã¬ã³ããªã³ã°ã³ãŒãããã³ãã¬ãŒãã®ã€ã³ã¯ã«ãŒãã«çœ®ãæããŸããã ãã®ããã«ããŠããŠãŒã¶ãŒã¢ãã¿ãŒã䜿çšããŠãããè¯ãããŒãžã§ã³ã®ã¬ã³ããªã³ã°ãååŸããŸãã
以äžã¯ãçŸåšã®ç¶æ
ã®ã¡ã€ã³ããŒãžã®ã¹ã¯ãªãŒã³ã·ã§ããã§ãã

ãŠãŒã¶ãŒãããã¡ã€ã«ããŒãž
ããã§ãã¡ã€ã³ããŒãžãå®æããŸããã ãŸãããŠãŒã¶ãŒãããã¡ã€ã«ã«ã¯ã¡ãã»ãŒãžãå«ããŸãããããã¹ãŠã§ã¯ãªãããããã¡ã€ã«ã®ææè
ã®ã¿ãå«ããŸããã äžè²«æ§ãä¿ã€ã«ã¯ãã¡ã€ã³ããŒãžã«åãããŠãããã¡ã€ã«ããŒãžãå€æŽããå¿
èŠããããŸãã
å€æŽã¯ãã¡ã€ã³ããŒãžã§è¡ã£ãå€æŽãšåæ§ã§ãã ããã«ãç§ãã¡ãããå¿
èŠãããããšã®çããªã¹ãããããŸãïŒ
- ããŒãžçªå·ãåãäœåãªã«ãŒããè¿œå ããŸã
- åŒæ°ãããŒãžçªå·ãšãšãã«ãã¥ãŒé¢æ°ã«è¿œå ããŠå²ãåœãŠãŸã1
- åœã®æçš¿ãããŒã¿ããŒã¹ã®å®éã®æçš¿ã«çœ®ãæããããŒãžã«åå²ããŸã
- ããŒãžããŒã·ã§ã³ãªããžã§ã¯ãã䜿çšããããã«ãã³ãã¬ãŒããæŽæ°ããŸã
ãããã¯ããã¥ãŒé¢æ°
( app/views.py)
ã®æŽæ°
( app/views.py)
ïŒ
@app.route('/user/<nickname>') @app.route('/user/<nickname>/<int:page>') @login_required def user(nickname, page = 1): user = User.query.filter_by(nickname = nickname).first() if user == None: flash('User ' + nickname + ' not found.') return redirect(url_for('index')) posts = user.posts.paginate(page, POSTS_PER_PAGE, False) return render_template('user.html', user = user, posts = posts)
, ( ), .
ãã³ãã¬ãŒãã®å€æŽãéåžžã«ç°¡åã§ã
( app/templates/user.html)
ïŒ
<!-- posts is a Paginate object --> {% for post in posts.items %} {% include 'post.html' %} {% endfor %} {% if posts.has_prev %}<a href="{{ url_for('user', nickname = user.nickname, page = posts.prev_num) }}"><< Newer posts</a>{% else %}<< Newer posts{% endif %} | {% if posts.has_next %}<a href="{{ url_for('user', nickname = user.nickname, page = posts.next_num) }}">Older posts >></a>{% else %}Older posts >>{% endif %}
æåŸã®èšè
以äžã«ããã®èšäºã§è¡ã£ããã¹ãŠã®å€æŽãå«ã
microblog
ã¢ããªã±ãŒã·ã§ã³ã®æŽæ°ããŒãžã§ã³ãæçš¿ããŸãã
microblog-0.9.zipãããŠã³ããŒãã
ãŸãããã€ãã®ããã«ãããŒã¿ããŒã¹ã¯ãããŸãããèªåã§äœæããå¿
èŠããããŸãã ãã®äžé£ã®èšäºã«åŸããšããã®æ¹æ³ãããããŸãã ããã§ãªãå Žåã¯ãããŒã¿ããŒã¹ã®èšäºã«æ»ã£ãŠèª¿ã¹ãŠãã ããã
ãã€ãã®ããã«ãç§ããã©ããŒããŠãããŠããããšãã 次ã®èšäºã§ãäŒãããŸãããã
ãã²ã«