[python]Flaskで作る簡単な連絡先管理アプリと、HTML・CSS分離によるコードの管理


# はじめに

今回は、PythonのWebフレームワーク **Flask** を使って、簡単な連絡先管理アプリを作成し、その中で **HTML** と **CSS** を分離してコードの管理を改善する方法について説明します。

## プロジェクトの概要

このプロジェクトでは、以下の基本的な機能を持ったアプリを作成します。

- フォームから名前、電話番号、メールアドレスを登録
- 登録された連絡先を表形式で表示
- Flaskを使用したバックエンド処理
- HTMLとCSSの分離による効率的なコード管理

## 完成イメージ
![スクリーンショット 2024-10-17 19.19.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/aeaf8269-a5d8-a554-4ea8-c2f572e9c831.png)


## プロジェクトの構成

まず、プロジェクトのディレクトリ構成は以下のようになります。

```
project/
│
├── app.py           # FlaskアプリケーションのPythonコード
├── templates/
│    └── index.html  # WebページのHTMLコード
├── static/
│    └── style.css   # CSSファイル
└── contacts.json    # 連絡先データを保存するJSONファイル
```

### 1. Pythonコード (`app.py`)

Flaskの基本的な構成を使って、フォームデータの処理と、連絡先リストの表示を行います。

```python
from flask import Flask, render_template, request, redirect, url_for
import json

app = Flask(__name__)

# 連絡先データを読み込む関数
def load_contacts():
    try:
        with open('contacts.json', 'r') as f:
            return json.load(f)
    except FileNotFoundError:
        return []

# 連絡先データを書き込む関数
def save_contacts(contacts):
    with open('contacts.json', 'w') as f:
        json.dump(contacts, f)

@app.route('/')
def index():
    contacts = load_contacts()
    return render_template('index.html', contacts=contacts)

@app.route('/add', methods=['POST'])
def add_contact():
    name = request.form['name']
    phone = request.form['phone']
    email = request.form['email']

    # 新しい連絡先データを追加
    new_contact = {'name': name, 'phone': phone, 'email': email}
    contacts = load_contacts()
    contacts.append(new_contact)
    save_contacts(contacts)

    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)
```

### 2. HTMLコード (`templates/index.html`)

`index.html` では、フォームの構造と連絡先のリストを表示する部分を記述します。CSSは外部ファイル `style.css` に分離してリンクしています。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>連絡先管理アプリ</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <h1>連絡先管理アプリ</h1>

    <form action="/add" method="POST">
        <label for="name">名前:</label>
        <input type="text" id="name" name="name" required>
        <label for="phone">電話番号:</label>
        <input type="text" id="phone" name="phone" required>
        <label for="email">メールアドレス:</label>
        <input type="email" id="email" name="email" required>
        <input type="submit" value="連絡先を追加">
    </form>

    <h2>現在の連絡先リスト</h2>

    <table>
        <tr>
            <th>名前</th>
            <th>電話番号</th>
            <th>メールアドレス</th>
        </tr>
        {% for contact in contacts %}
        <tr>
            <td>{{ contact.name }}</td>
            <td>{{ contact.phone }}</td>
            <td>{{ contact.email }}</td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>
```

ここでは、CSSは `static/style.css` というファイルから読み込まれています。Flaskでは `url_for` 関数を使って静的ファイル（CSSやJavaScriptファイルなど）を参照します。

### 3. CSSコード (`static/style.css`)

デザインをシンプルかつ見やすくするために、CSSを外部ファイルに分離します。フォームやテーブルのスタイルを整えて、レスポンシブ対応も行っています。

```css
body {
    font-family: 'Helvetica Neue', Arial, sans-serif;
    background-color: #f7f9fc;
    margin: 0;
    padding: 20px;
}

h1 {
    text-align: center;
    color: #333;
}

form {
    max-width: 500px;
    margin: 0 auto 20px auto;
    padding: 20px;
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

label {
    display: block;
    margin-bottom: 8px;
    color: #555;
}

input[type="text"], input[type="email"] {
    width: 100%;
    padding: 10px;
    margin-bottom: 15px;
    border: 1px solid #ddd;
    border-radius: 5px;
    box-sizing: border-box;
}

input[type="submit"] {
    width: 100%;
    padding: 10px;
    background-color: #007BFF;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    font-size: 16px;
}

input[type="submit"]:hover {
    background-color: #0056b3;
}

table {
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
    border-collapse: collapse;
    background-color: white;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

th, td {
    padding: 15px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

th {
    background-color: #007BFF;
    color: white;
}

td {
    color: #555;
}

tr:hover {
    background-color: #f1f1f1;
}

@media (max-width: 600px) {
    body {
        padding: 10px;
    }
    form, table {
        width: 100%;
    }
    input[type="submit"] {
        font-size: 14px;
    }
}
```

このCSSでは、フォームやテーブルのレイアウトを調整し、さらにモバイル対応も行っています。レスポンシブデザインにより、画面幅が600px以下になるとフォームやボタンのサイズが自動調整されます。

## 実行方法

1. Flaskサーバーを起動します：

```bash
python app.py
```

2. ブラウザで `http://127.0.0.1:5000/` にアクセスすると、アプリケーションが表示されます。

## まとめ

今回のプロジェクトでは、Flaskを使用して連絡先管理アプリを作成し、HTMLとCSSを分離して効率的なコード管理を実現しました。HTMLとCSSを分離することで、デザインと機能を独立させ、保守性が向上します。

この記事では簡単な例を示しましたが、他のプロジェクトでも同様のアプローチを採用することで、開発がスムーズに進むはずです。ぜひ試してみてください！