python flask 入門 No.4

Python

前回の記事ではデータベースのモデル定義をmodels.pyに書きました

今回は各ページを表示するロジックとなるviews.pyを書いていきます

・ディレクトリ構成

project/
├── flaskr/
│   ├── __init__.py      # アプリケーションの初期化
│   ├── models.py        # データベースのモデル定義
│   ├── views.py         # ルートやビューのロジック
│   └── templates/
│       └── index.html   # テンプレート
└── run.py               # アプリケーションの起動スクリプト

・コード

WEBアプリケーションの表示するページの決定や、データベースの操作を行うviews.pyのファイル全体を以下に表示します

長くなりますが、各機能ごとに解説していきます

from flask import render_template, request, redirect, url_for
from . import db
from .models import Todo
from datetime import datetime

def register_routes(app):
# トップページの表示
    @app.route('/')
    def index():
        """ タスク一覧を表示"""
        todos = Todo.query.order_by(Todo.due_date).all()
        return render_template('index.html', todos=todos)

# タスク追加ページの表示
    @app.route('/add', methods=['GET', 'POST'])
    def add_todo():
        """POSTの場合(タスク追加フォームを送信時)"""
        if request.method == 'POST':
            title = request.form.get('title')
            description = request.form.get('description')
            due_date_str = request.form.get('due_date')

            # 空チェック
            if not title.strip():  
                return "Title is required!", 400

            # 日付を変換(空の場合はNone)
            due_date = datetime.strptime(due_date_str, '%Y-%m-%d') if due_date_str else None

            new_todo = Todo(title=title, description=description, due_date=due_date)
            db.session.add(new_todo)
            db.session.commit()
            return redirect(url_for('index'))

        """GETの場合(タスク追加フォームを表示したい時)"""
        return render_template('add.html')  

# タスク削除のデータベース操作
    @app.route('/delete/<int:todo_id>')
    def delete_todo(todo_id):
        """指定したIDのタスクを削除"""
        todo = Todo.query.get_or_404(todo_id)
        db.session.delete(todo)
        db.session.commit()
        return redirect(url_for('index'))

# タスク編集のページ表示
    @app.route('/update/<int:todo_id>', methods=['GET', 'POST'])
    def update_todo(todo_id):
        """POSTの場合(指定したIDのタスクを編集)"""
        todo = Todo.query.get_or_404(todo_id)
        if request.method == 'POST':
            title = request.form.get('title')
            description = request.form.get('description')
            due_date_str = request.form.get('due_date')

            # 空チェック
            if not title.strip():  
                return "Title is required!", 400

            todo.title = title
            todo.description = description
            todo.due_date = datetime.strptime(due_date_str, '%Y-%m-%d') if due_date_str else None

            db.session.commit()
            return redirect(url_for('index'))
        """GETの場合(編集用フォームを表示)"""
        return render_template('update.html', todo=todo)  

# 必ず最後にこの関数を呼び出す
def init_views(app):
    register_routes(app)

トップページの表示

todos = Todo.query.order_by(Todo.due_date).all()
todoテーブルの全てから検索され、due_dateによって並び替えられたレコードをリスト形式で取得

return render_template(‘index.html’, todos=todos)
index.htmlページを表示(todosに先程のリスト形式のtodosを代入)

タスクのデータベース追加、タスク追加ページの表示

if request.method == ‘POST’:
POSTの場合(タスク追加フォームを送信時)入力フォームの値を各変数に代入


if not title.strip():
return “Title is required!”, 400

titleが空文字ならば、エラー400を表示
400は「Bad Request(リクエストが不正)」を意味します

due_date = datetime.strptime(due_date_str, ‘%Y-%m-%d’) if due_date_str else None
文字列の日付をpythonのdatetime型の数値に変換、日付がなければNoneに変換

new_todo = Todo(title=title, description=description, due_date=due_date)
db.session.add(new_todo)
db.session.commit()

それぞれの値をデータベースに追加

return redirect(url_for(‘index’))
自動的にトップページへ戻るため、indexページへリダイレクト


return render_template(‘add.html’)
GETの場合、タスク追加フォームを表示

タスク削除のデータベース操作

@app.route(‘/delete/<int:todo_id>’)
delete/index番号 へのリクエストがあった時の処理


def delete_todo(todo_id):
todo = Todo.query.get_or_404(todo_id)

指定されたらindex番号のタスクがない場合、404エラーを返します

db.session.delete(todo)
db.session.commit()

指定したindex番号のタスクを削除

return redirect(url_for(‘index’))
indexページへリダイレクト

タスク編集ページの表示

タスク追加ページのコードとほぼ同じです

アプリケーションにルート(URLパス)を登録する

def init_views(app):
register_routes(app)

アプリケーションの規模が大きくなると、ルートを複数のモジュールに分けて管理することが一般的です
すべてのルートを一括で登録する処理を1つの関数にまとめることで、コードの可読性やメンテナンス性を向上させます

難しい内容でしたが、以上がviews.pyの解説となります

次回は、このviews.pyによって表示されるhtmlの解説をしていきたいと思います

コメント