前回の記事

トップページのプログラムを作成
トップページに記事一覧を表示するためのプログラムを書きます。

でapp.pyに
Flask,render_template
だけ読み込ませているので新しく次のように書き足してください。
from flask import Flask,render_template,session,request,redirect,url_for
from models.database import Base,db_session
from models.models import BlogContent,Users
新しくインポートしたライブラリについて
session
FlaskでSessionを扱うためのライブラリです。
request
formに入力されたデータを読み取るためのライブラリです。
redirect
リダイレクトを簡単に行えるようにするライブラリです。
url_for
関数名を指定するとそれに対応するURLを返してくれるライブラリです。
例えば次のようなプログラムを組んで/homeにアクセスするすると/testpageにリダイレクトされて画面には”testpage”と表示されます。
@app.route("/testpage")
def test():
return "testpage"
@app.route("/home")
def home
return redirect(url_for("test"))
Base db_session
この2つはデータベースを操作するためのライブラリです。
BlogContent Users
モデルの設定データです。
記事を表示させるプログラム
必要なライブラリを読み込めたので記事を表示させるプログラムを書いていきます。
はじめに①で下のようなプログラムを書いていたと思いますが、必要ないので消してください。
@app.route("/template")
def template():
return render_template("index.html",message="これはテンプレートです")
次にindex関数を次のように書き換えてください。
app.py
@app.route("/")
def index():
if ("name" in session):
if (not session["name"] == None):
app.add_template_global(name="status",f="login")
else:
app.add_template_global(name="status",f="n")
posts = db_session.query(BlogContent).order_by(BlogContent.id.desc())
return render_template("index.html",posts=posts)
最初のif文ではログイン状態を確認してログインしていたらstatus関数にユーザー名を入れています。
add_template_globalを使うとメインテンプレートでも変数を利用できます。
次のpostsにはデータベースからBlogContentのデータを降順で入れています。
ここでプログラムを変えることで検索などの細かい設定をすることも可能です。
投稿データが入ったpostsはindex.html上のfor文で1件ずつ表示されます。
データベースに投稿データを入れてテストしてみる
記事一覧を表示できるようになったのでデータを入れて確かめてみます。
まだ投稿ページがないのでターミナルでプログラムを実行して直接入れます。
myblogフォルダに移動してPython3を開き次のように打ってください。
from models.database import db_session
from models.models import BlogContent
data = BlogContent("テスト","本文")
db_session.add(data)
db_session.commit()
これでデータを追加できたのでpython3 run.pyでサーバーを起動してブラウザで表示するとタイトルが表示されているはずです。

ログイン・ログアウトのプログラムを作る
次にログイン・ログアウトのプログラムを実装します。
app.pyに次のように追加してください
app.py
app.secret_key = "UfriMzp7nEQcKSf"
@app.route("/login")
def login():
if ("name" in session):
if (not session["name"] == None):
return redirect(url_for("index"))
else:
app.add_template_global(name="status",f="n")
return render_template("login.html")
@app.route("/login",methods=["post"])
def login_check():
name = request.form["name"]
password = request.form["password"]
user = db_session.query(Users).filter_by(name = name,password = password).first()
if user:
session["name"] = name
return redirect(url_for("index"))
else:
return render_template("login.html",message="NameまたはPasswordが違います")
@app.route("/logout")
def logout():
session.pop("name",None)
return redirect(url_for("index"))
app.secret_keyにはブラウザのセッションを使うためのキーを指定しています。適当に書き換えてください。
login関数ではログインページのテンプレートを返しています。
login_checkではフォームに入力されたユーザー情報が正しければセッションにユーザー名を書き込んでいます。
ログアウトではセッションのデータを消しています。
今回のログインシステムはセキュリティ的によろしくないので絶対に本番環境で使わないでください。
テスト
先程投稿データを入れたようにターミナルからユーザーデータを追加します。
from models.database import db_session
from models.models import Users
data = Users("{名前}","{パスワード(平文)}")
db_session.add(data)
db_session.commit()
サーバーを実行して/loginに追加した情報を入れることでログインできるはずです。
記事投稿ページのプログラムを作る
次に記事投稿ページにプログラムを実装します。
次のコードをapp.pyに追加してください。
@app.route("/add")
def add():
if ("name" in session):
if (not session["name"] == None):
app.add_template_global(name="status",f="login")
return render_template("add_post.html")
else:
return redirect(url_for("login"))
@app.route("/add",methods=["post"])
def add_post():
if ("name" in session):
if (not session["name"] == None):
app.add_template_global(name="status",f="login")
if (request.form["title"]) and (request.form["body"]):
title = request.form["title"]
body = request.form["body"]
check_title = db_session.query(BlogContent).filter_by(title = title).first()
if check_title:
message = title + "は既に使われています"
return render_template("add_post.html",message=message,title=title,body=body)
else:
post_data = BlogContent(title,body)
db_session.add(post_data)
db_session.commit()
return redirect(url_for("post",title=title))
else:
if request.form["title"]:
return render_template("add_post.html",title=request.form["title"])
if request.form["body"]:
return render_template("add_post.html",body=request.form["body"])
if (not request.form["title"]) and (not request.form["body"]):
return redirect(url_for("add"))
else:
return redirect(url_for("login"))
addでは投稿フォームをログインしているユーザーに表示しています。
add_postはタイトルの被り等を確認した上でデータベースに追加しています。
サーバーを立ち上げてログインして状態で/addにアクセスすると投稿フォームが表示されるので適当に入力して見てください。
投稿を表示するプログラムをまだ実装していないので投稿後にエラーが出ると思いますが、トップページに戻ることで実際に投稿されているか確かめることができます。
記事を表示するプログラムを実装
投稿できるようになったので表示するプログラムを実装します。
app.py
@app.route("/post/<title>")
def post(title):
if ("name" in session):
if (not session["name"] == None):
app.add_template_global(name="status",f="login")
else:
app.add_template_global(name="status",f="n")
post_data = db_session.query(BlogContent).filter_by(title=title).first()
if post_data:
return render_template("post.html",post=post_data)
else:
return render_template("notfound.html")
@app.route("/post")
def post_none():
return redirect(url_for("index"))
/post/タイトルにアクセスがあるとタイトルを取得してデータベースで検索・表示しています。
記事を編集・削除するプログラムを実装
@app.route("/edit/<title>")
def edit(title):
if ("name" in session):
if (not session["name"] == None):
app.add_template_global(name="status",f="login")
post_check = db_session.query(BlogContent).filter_by(title = title).first()
if post_check:
return render_template("edit_post.html",post=post_check)
else:
return redirect(url_for("index"))
else:
return redirect(url_for("login"))
@app.route("/edit/<title>",methods=["post"])
def edit_update(title):
if ("name" in session):
if (not session["name"] == None):
app.add_template_global(name="status",f="login")
post = db_session.query(BlogContent).filter_by(title = title).first()
if post:
if (request.form["title"]) and (request.form["body"]):
new_title = request.form["title"]
new_body = request.form["body"]
if (title == new_title):
post.body = new_body
db_session.commit()
return redirect(url_for("post",title=title))
else:
post_check = db_session.query(BlogContent).filter_by(title = new_title).first()
if post_check:
message = new_title+"は既に使われています"
return render_template("edit_post.html",post=post_check,message=message)
else:
post.title = new_title
post.body = new_body
db_session.commit()
return redirect(url_for("post",title=new_title))
else:
return redirect(url_for("edit",title=title))
else:
return redirect(url_for("index"))
else:
return redirect(url_for("login"))
@app.route("/delete/<title>")
def delete(title):
if ("name" in session):
if (not session["name"] == None):
app.add_template_global(name="status",f="login")
post_check = db_session.query(BlogContent).filter_by(title = title).first()
if post_check:
post = db_session.query(BlogContent).filter_by(title = title).first()
db_session.delete(post)
db_session.commit()
return redirect(url_for("index"))
else:
return redirect(url_for("index"))
else:
return redirect(url_for("login"))
編集用のプログラムは記事を投稿するプログラムの応用でできています。
最後にブログの指定&404エラーの設定
一通りのプログラムがかけたのでブログ名を指定して404エラーの場合に表示するページを設定します。
blog_name = "MasuBlog"
app.add_template_global(name="blog_name",f=blog_name)
@app.errorhandler(404)
def page_not_found(error):
return render_template("notfound.html"), 404
完成
完成したのでサーバーを立ち上げていろいろ試してみてください。
最後の方説明が適当になっているのでなにかあればツイッターやコメント欄までお願いします。
最後まで読んでいただきありがとうございました。
コメント