0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python 初心者 Webアプリ開発

Last updated at Posted at 2024-09-26

目次

1.アプリ開発のきっかけ
2.開発方法
3.修正・改良時の工夫
4.ソースコード

1.アプリ開発のきっかけ

転職活動のためです。
私は新卒から5年間営業として続けてきましたが、技術系の職種に興味を持ち、独学でプログラミングを始めました。
実際にWebアプリを作成することで、実践力を身に付けたいと考えています。

2.開発方法

Youtubeにて、以下の動画を参考にしました。
https://youtu.be/EQIAzH0HvzQ?si=jUDIGKnPLmBChcXj

PythonプログラミングYoutuberのサプーさんです。
動画で環境構築の方法も含めて、書店の新刊情報を記録・表示するアプリの作成方法を解説しています。

動画で解説している内容をもとに、こちらの通りアプリを作成しました。
こちらはホーム画面です。「サプー書店」という書店を想定し、今月の新刊一覧を表示しています。
(サプー版)ホーム.png

ホーム画面下部の「編集」リンクをクリックすると、新規登録画面に遷移します。こちらの画面で入荷日・タイトル・金額のデータを入力できます。
(サプー版)編集 新規登録.png

作成したうえで、以下のように改善したいと思いました。
①実用的に考えると、書店ではなく「読んだ本を記録するアプリ」として作成したい
②登録済みのレコードに対し、データを編集・削除する機能を実装

そこで、作成済みのコードに対して以下の通り改良を加えました。

①「読書記録」アプリとしての作成
・タイトルを「読書記録」に変更
・データベースのカラムを、「入荷日」「タイトル」「金額」から、「購入日」「タイトル」「感想」に変更(それに伴う変数も変更)

②編集・削除機能の追加
・HTMLにて、各レコードに対する編集ボタン・削除ボタンの追加
・新しくedit.htmlというファイルを作成し、編集の機能を追加 それに紐づく処理をmain.pyに追加
・main.pyに削除の処理を追加

その他微修正
・required属性を追加し、タイトルが空の状態で登録できないように改良
・新規登録するためのリンクの表示名を「編集」から「新規登録」に変更

▼ホーム画面
ホーム画面.png

▼新規登録画面
新規登録.png

▼編集画面
編集.png

3.修正・改良時の工夫

できるだけ動画の解説を参考に、「どこに何が、どういう意味合いで記載されているのか」を考えながら紐解きました。
自力で解決できない部分はChatGPTに質問し、コードを記述しました。
修正する内容は、システムのユーザになりきり、見た目や操作性で必要なものを考えました。

4.ソースコード

以下、7種類のファイルを作成しました。
・index.html
・form.html
・edit.html
・main.py
・init__.py
・db.py
・style.css

index.html

<!DOCTYPE html>  

<html lang="ja"> 
    <head>
        <meta charset="UTF-8">
        <title>Webアプリ</title>
        <link rel="stylesheet" href="{{url_for('static',filename='style.css')}}">
    </head>
    <body>
        <h1>読書記録</h1>
            {% if books == [] %}
                <p>読書記録はありません</p>
            {% else %}
                <table border="1">
                    <tr>
                        <th>購入日</th>
                        <th>タイトル</th>
                        <th>感想</th>
                    </tr>
            {% for book in books %}
                <tr>
                    <td><p>{{ book.purchase_day }}</p></td>
                    <td><p>{{ book.title }}</p></td>
                    <td><p>{{ book.report }}</p></td>
                    <td><a href="{{ url_for('edit', title=book['title']) }}">編集</a></td> 
                    <td>
                    <form method="post" action="{{ url_for('delete', title=book.title) }}"> 
                    <input type="submit" value="削除">
                </tr>   
            {% endfor %}
        </table>
    {% endif %}
    <a href="{{ url_for('form') }}">新規登録</a> <!--ボタンを押したときに、formを表示する formはmain.pyで指定-->    
</body>
</html>

form.html

<!DOCTYPE html>  

<html lang="ja"> 
    <head>
        <meta charset="UTF-8">
        <title>読書記録</title>
        <link rel="stylesheet" href="{{url_for('static',filename='style.css')}}">
    </head>
    <body>
        <h1>読書記録</h1>
        <form method="post" action="{{url_for('register')}}">  <!--post:リクエストの種類 action:登録ボタンを押した後に実行する関数(registerはmain.pyで記述)-->
            <table border="1">
            <tr>
                <th>購入日</th>
                <th>タイトル</th>
                <th>感想</th>
            </tr>

<!--テキストボックスの作成-->
            <tr>
                <td><input type="text" name="purchase_day"></td> 
                <td><input type="text" name="title" required></td> <!-- required:空の状態で登録しようとするとエラーを表示 -->
                <td><input type="text" name="report"></td>
            </tr>

        </table>
        </br>
        <input type="submit" value="登録">  <!--登録ボタンの作成-->
        </form>
    </body>
</html>

edit.html

<!DOCTYPE html>  
<html lang="ja"> 
<head>
    <meta charset="UTF-8">
    <title>読書記録 - 編集</title>
    <link rel="stylesheet" href="{{url_for('static',filename='style.css')}}">
</head>
<body>
    <h1>本の情報を編集</h1>
    <form method="post" action="{{ url_for('update', title=book['title']) }}">
        <label for="purchase_day">購入日:</label>
        <input type="text" name="purchase_day" value="{{ book['purchase_day'] }}"><br>
        
        <label for="title">タイトル:</label>
        <input type="text" name="title" value="{{ book['title'] }}"><br>
        
        <label for="report">感想:</label>
        <input type="text" name="report" value="{{ book['report'] }}"><br>
        
        <input type="submit" value="更新">
    </form>
    <a href="{{ url_for('index') }}">戻る</a>
</body>
</html>

main.py

from flaskr import app  #flaskアプリのオブジェクトをインストール
from flask import render_template, request, redirect, url_for
import sqlite3
DATABASE='database.db'

@app.route('/')
def index():
    con = sqlite3.connect(DATABASE)
    db_books=con.execute('SELECT*FROM books').fetchall()
    con.close()

    books=[]
    for row in db_books:
       books.append({'title':row[0], 'report':row[1], 'purchase_day':row[2]})
    return render_template(
        'index.html',
        books=books
    ) 

@app.route('/form')
def form():
  return render_template(
     'form.html' #新規登録ボタンが押された時の表示の仕方を記述(ボタンはindex.htmlのAタグ)
  )

#登録処理
@app.route('/register', methods=['POST'])  #/register:register関数の内容がURLとして紐づく postのリクエストの場合にregisterが呼び出される
def register():
   title=request.form['title']
   report=request.form['report']
   purchase_day=request.form['purchase_day']

   con=sqlite3.connect(DATABASE)
   con.execute('INSERT INTO books VALUES(?,?,?)',
              [title,report,purchase_day]) #1つ目の?にtitle、2つ目の?にreport、3つ目の?にpurchase_dayの値に当てはまり、booksのテーブルに登録される
   con.commit()
   con.close()
   return redirect(url_for('index')) #main.pyのindexのURLにリダイレクトされるようになる


# 編集処理(登録済みのレコード)
@app.route('/edit/<string:title>', methods=['GET'])
def edit(title):
    con = sqlite3.connect(DATABASE)
    book = con.execute('SELECT * FROM books WHERE title = ?', (title,)).fetchone()
    con.close()
    
    if book:
        book_data = {'title': book[0], 'report': book[1], 'purchase_day': book[2]}
        return render_template('edit.html', book=book_data)
    else:
        return redirect(url_for('index'))

# 更新処理
@app.route('/update/<string:title>', methods=['POST'])
def update(title):
    new_title = request.form['title']
    new_report = request.form['report']
    new_purchase_day = request.form['purchase_day']

    con = sqlite3.connect(DATABASE)
    con.execute('UPDATE books SET title = ?, report = ?, purchase_day = ? WHERE title = ?',
                (new_title, new_report, new_purchase_day, title))
    con.commit()
    con.close()
    
    return redirect(url_for('index'))

# 本の削除処理
@app.route('/delete/<string:title>', methods=['POST'])
def delete(title):
    con = sqlite3.connect(DATABASE)
    con.execute('DELETE FROM books WHERE title = ?', (title,))
    con.commit()
    con.close()
    
    return redirect(url_for('index'))

init__.py

from flask import Flask 
app = Flask(__name__)
import flaskr.main

from flaskr import db
db.create_books_table()

db.py

import sqlite3 

DATABASE='database.db'

def create_books_table():
    con = sqlite3.connect(DATABASE) #DATABASEへの接続用オブジェクトを作る
    con.execute("""
        CREATE TABLE IF NOT EXISTS books(
            title TEXT, 
            report TEXT, 
            purchase_day TEXT)
        """) 

    con.close()

#SQLite:flaskをインストールすると初めから入っている 表形式のデータをためておくことができる 小規模で、1ファイルだけに貯めておくもの

style.css

h1{
    position: relative;
    background:#dfefff;
    box-shadow: 0px 0px 0px 5px #dfefff;
    border: dashed 2px white;
    padding: 0.2em 0.5em;
    color: #454545;
}

h1:after {
    position: absolute;
    content: '';
    left: -7px;
    top: -7px;
    border-width: 0 0 15px 15px;
    border-style: solid;
    border-color: #fff #fff #a8d4ff;
    box-shadow: 1px 1px 1px rgba(0,0,0,0.15);
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?