ビジネスパーソン・ガジェット置場 empty lot for business

営業や仕事、それに伴う生活を便利に楽にするツール、ガジェットを作ります。既にあるツールも自分用にカスタマイズ。

python: Flaskアプリの作成⑥ 投稿した記事の編集ページの作成

備忘録です。

今回は、前回、投稿できるようにした記事を編集するページを作成する際の備忘録です。

ブログ編集

投稿した記事の編集ページの作成

今回は、投稿時には使用しなかった項目として

  • 完了日
  • ステータス

という二つの項目を編集できるようにします。

 

※やりたいことを登録するというページになるので、やりたいことをやって完了したら完了日を入れる。さらに完了したものはステータスを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

# やりたいことを編集するページ
# やりたいことの個別のidを取得して渡します
@app.route('/aspirations/edit/<int:id>', methods=['GET', 'POST'])
def edit_aspiration(id):
 # 該当がなければ404ページを表示します
    aspiration = Aspiration.query.get_or_404(id)
    form = AspirationForm()
        # フォームが投稿された際の処理(フォームに記載されたものを変数にいれてDBに追加します)
    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()
                # 投稿した後に全体のページに返したいのでrender_templateで全体ページに進みます
        aspirations = Aspiration.query.order_by(Aspiration.created_at)
        return render_template('aspirations.html', aspirations=aspirations)
        # 以下は最初に編集ページにアクセスした際にDBに登録されている情報を表示するものになります
    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条件文で完了日がNone 出ない場合完了日を表示するようにします
    {% if aspiration.completed_at %}
        # 追記した完了日
      <small>完了日:{{ aspiration.completed_at.strftime('%Y-%m-%d')}}</small><br/>
    {% endif %}
    {{ aspiration.content }} <br/><br/>
  </div>
{% endfor %}
{% endblock %}

 

最終的に一覧表示はこんな感じでできました。

※一番上のテストは完了日を入れたので完了日が入っています。

その下は完了日が入っていないので作成日しか表示されていません。