備忘録です。
今回は、前回、投稿できるようにした記事を編集するページを作成する際の備忘録です。
投稿した記事の編集ページの作成
今回は、投稿時には使用しなかった項目として
という二つの項目を編集できるようにします。
※やりたいことを登録するというページになるので、やりたいことをやって完了したら完了日を入れる。さらに完了したものはステータスを1、未完了のものはステータスを0として管理したいのでそれも編集できるようにします。
※ちなみに、これら二つの項目はモデル作成時に既にモデルに加えていました。
python: Flaskアプリの作成③ Flaskでデータベースに投稿するページを作る - ビジネスパーソン・ガジェット置場 empty lot for business
なので現時点でモデルはこのような項目となっています。
# app.py
class Aspiration(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(255))
content = db.Column(db.Text)
status = db.Column(db.Integer)
created_at = db.Column(db.DateTime, default=datetime.now(pytz.timezone('Asia/Tokyo')))
completed_at = db.Column(db.DateTime)
その1 必要なライブラリのクラスをインストール
今回、完了日という日付を扱うのでフォームで日付を扱えるフィールドを追加でインストールします。
from wtforms import DateField, StringField, SubmitField, PasswordField, BooleanField, ValidationError, TextAreaField
※赤文字のDateFieldが今回追加したものになります。
その2 フォームにstatusとcreated_atという項目を追記
# app.py
class AspirationForm(FlaskForm):
title = StringField('Title', validators=[DataRequired()])
content = StringField('Content', validators=[DataRequired()], widget=TextArea())
status = StringField('Staus')
completed_at = DateField('Complete date')
submit = SubmitField('Submit')
※submitの上の2行を追記しています。
その3 やりたいことを編集するページを作成
# app.py
@app.route('/aspirations/edit/<int:id>', methods=['GET', 'POST'])
def edit_aspiration(id):
aspiration = Aspiration.query.get_or_404(id)
form = AspirationForm()
if form.validate_on_submit():
aspiration.title = form.title.data
aspiration.content = form.content.data
aspiration.status = form.status.data
aspiration.completed_at = form.completed_at.data
db.session.add(aspiration)
db.session.commit()
aspirations = Aspiration.query.order_by(Aspiration.created_at)
return render_template('aspirations.html', aspirations=aspirations)
form.title.data = aspiration.title
form.content.data = aspiration.content
form.status.data = aspiration.status
form.completed_at.data = aspiration.completed_at
return render_template('edit_aspiration.html', form=form)
その4 編集用のページを準備します
# edit_aspiration.html
{% extends "base.html" %}
{% block content %}
<h1>やりたいことを編集する</h1>
<br/>
<div class="shadow p-3 mb-5 bg-body rounded">
<form method="POST">
{{ form.hidden_tag() }}
{{ form.title.label(class="form-label") }}
{{ form.title(class="form-control") }}
<br/>
{{ form.content.label(class="form-label") }}
{{ form.content(class="form-control") }}
<br/>
{{ form.status.label(class="form-label") }}
{{ form.status(class="form-control") }}
<br/>
{{ form.completed_at.label(class="form-label") }}
{{ form.completed_at(class="form-control") }}
<br/>
{{ form.submit(class="btn btn-secondary") }}
</form>
</div>
{% endblock %}
※statusとcompleted_atの項目を追記しました。
ちなみに、Date Fieldをフォームのクラスに追記していますが、入力フォームは下記のようにカレンダーで選択できるようになっています。
その5 一覧を表示するページに完了日を表示できるようにする
statusは別途管理するので完了日だけ表示できるようにします。この際、完了日をstrftimeで表示形式の変更をしています。ただ、strftimeはNoneには使用できないので、そもそも、完了日が記入されたものだけ完了日を表示できるようにifで条件付けもしています。
# aspirations.html
{% extends "base.html"%}
{% block content %}
<a href="{{ url_for('add_aspiration')}}" class='btn btn-outline-primary float-end mt-2'>やりたいこと登録</a>
<h1 class="mt-4">やりたいこと一覧</h1>
{% for aspiration in aspirations %}
<div class="shadow p-3 mb-5 bg-body rounded">
<h2>{{ aspiration.title }}</h2>
<small>作成日:{{ aspiration.created_at.strftime('%Y-%m-%d %H:%M') }}</small><br/>
{% if aspiration.completed_at %}
<small>完了日:{{ aspiration.completed_at.strftime('%Y-%m-%d')}}</small><br/>
{% endif %}
{{ aspiration.content }} <br/><br/>
</div>
{% endfor %}
{% endblock %}
最終的に一覧表示はこんな感じでできました。
※一番上のテストは完了日を入れたので完了日が入っています。
その下は完了日が入っていないので作成日しか表示されていません。