main.py 更新日:2024/12/31 W010

2024年12月31日火曜日

source code 公開

t f B! P L
■■
#******************************************************************************#
# ファイル名:main.py
# バージョン:p0001 Ver1.0
# 機能:
# 作成日:2024/11/25
# 更新日:2024/12/31 W010
#*******************************************************************************#

import os
import json
from ulid import ULID  #--- 追加11 # ULIDクラスをインポート
from flask import Flask, render_template, request, redirect, Response, url_for # --- 追加10 url_for
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required #--- 追加 9 事前に $ pip install flask-login でインストール # 仮想環境の場合はpipenv
from flask_sqlalchemy import SQLAlchemy  #--- 追加 9 事前に $ pip install flask_sqlalchemy  でインストール # 仮想環境の場合はpipenv
from werkzeug.security import generate_password_hash, check_password_hash #--- 追加 9 パスワードのハッシュ化

from KDpay import PayManager #--- 追加 7-1

file_path = 'KDjson.json'

app = Flask(__name__)
# ------------------------------------------------------------------------------ #
#  ユーザーDBの作成 #--- 追加 9
# ------------------------------------------------------------------------------ #

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///user_flask.db'
app.config['SECRET_KEY'] = os.urandom(24) # パスワード設定 #--- 追加 9
db = SQLAlchemy(app) # DB設定 #--- 追加 9

login_manager = LoginManager()
login_manager.init_app(app)
# login_manager.login_view = "users.login" # login_viewのrouteを設定 

# ユーザーDBの作成 #--- 追加 9
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(255), nullable=False, unique=True)
    password = db.Column(db.String(255))

# 認証ユーザーの呼び出し方を定義する  #--- 追加 9
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# ------------------------------------------------------------------------------ #
# 
# ------------------------------------------------------------------------------ #
@app.route('/')
def hello_show():
    return 'Hello World!'

# ------------------------------------------------------------------------------ #
# 
# ------------------------------------------------------------------------------ #
@app.route('/index')
def index():
    insert_dict = {
        'insert_1': 'insert_1部分です。',
        'insert_2': 'insert_2部分です。',
    }
    return render_template('index.html', title='Webアプリテスト', insert_dict=insert_dict)
# ------------------------------------------------------------------------------ #
#  ユーザー管理  #--- 追加 9
# ------------------------------------------------------------------------------ #
'''''''''''''''''
signup
'''''''''''''''''
@app.route('/signup', methods=['GET', 'POST'])
def signup():
    if request.method == "POST":
        username = request.form.get('username')
        password = request.form.get('password')
        # Userのインスタンスを作成
        user = User(username=username, password=password) 
        # hashを使用する場合(def login():も修正必要箇所あり)
        # user = User(username=username, password=generate_password_hash(password, method='pbkdf2:sha256'))        
        db.session.add(user)
        db.session.commit()
        return redirect('login')
    else:
        return render_template('signup.html')
'''''''''''''''''
login
'''''''''''''''''
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == "POST":
        username = request.form.get('username')
        password = request.form.get('password')
        # Userテーブルからusernameに一致するユーザを取得
        user = User.query.filter_by(username=username).first()
        if user.password == password:
        # hashを使用する場合(def signup()も修正必要箇所あり)
        # if check_password_hash(user.password, password):
            login_user(user)

          # return redirect('/kakeibo') # 家計簿へ'''修正前''''''
            return redirect(url_for('kd', user_name = user.username)) # 家計簿へ #--- 修正10 
        
        else:
            # 入力したユーザー名のパスワードが間違っている場合
            # return "

パスワードが間違っています。

" return Response(status=404, response="ページが見つかりません。") else: return render_template('login.html') ''''''''''''''''' logout ''''''''''''''''' @app.route('/logout') @login_required # ログインしているユーザーのみに制限 #--- 追加 9 def logout(): logout_user() return redirect('login') # ------------------------------------------------------------------------------ # # 家計簿 # ------------------------------------------------------------------------------ # # @app.route('/kakeibo', methods=['GET', 'POST']) #--- 修正6-1 '''修正前''' @app.route('/kakeibo/', methods=['GET', 'POST']) #--- 修正10 @login_required # ログインしているユーザーのみに制限 #--- 追加 9 ★★テストのときはコメントアウト★★ # # def kd(): # '''修正前''' def kd( user_name ): #--- 修正10 # 既存ファイルを確認 if not os.path.exists(file_path): # 無ければ作成 with open( file_path, mode='w', encoding="UTF-8" ) as open_json: initial_list = [{ "month" : [] , # "月" "day" : [] , # "日" "content" : [] , # "内訳" "amount" : [] , # "金額" "id" : [] , # "ID" #--- 追加10-2 "user" : [] # "ユーザー" #--- 追加10 } ] json.dump( initial_list, open_json, indent=4, ensure_ascii=False) # ペイ(収支)データ管理用クラス(KDpay.py)オブジェクト作成 #--- 追加7 pay_manager = PayManager() # 一意なIDオブジェクト作成 main_key = str(ULID()) #--- 追加10-3 # JSONファイルを読み込んで、辞書型リストを作成 with open( file_path, mode='r', encoding="UTF-8") as open_json: json_load_list = json.load(open_json) # 読み込んだファイルをペイ(収支)データ管理用クラスオブジェクトに追加 --- 修正7 for pay_data in json_load_list: pay_manager.add_pay(pay_data) # ログイン中のユーザーの家計簿リストを作成 search_list = [ item for item in json_load_list if item['user'] == user_name ] #--- 追加10 # ------------------------------------------------------------------------------ # #### HTTPリクエスト #### GETメソッド受信 # --- 修正6 if request.method == 'GET': # 更新した辞書型リストを送信し、HTMLをレンダリング # return render_template('kakeibo_test_json/kd.html', title='kakeibo', pay_list = pay_manager.pay_data_list) #--- 修正7-4 '''修正前'''''' return render_template('kakeibo_test_json/kd.html', title='kakeibo',user_name = user_name , pay_list = search_list ) #--- 修正10 # ------------------------------------------------------------------------------ # #### HTTPリクエスト ####   POSTメソッド受信 ####  「削除」 #### ボタンが押されたときの処理  # --- 追加 7 if request.method == 'POST' and request.form.get('delete_number') != None : # number = int( request.form.get('delete_number') ) - 1 #--- 修正前 delete_target_id_number = int( request.form.get('delete_number') ) - 1 # 入力された削除番号を整数型に変換、リストの要素番号が0から始まるため1マイナス #--- 修正10-2 #--- 以下4行、追加10-2 search_list_id_list = [d.get('id') for d in search_list] # 個別ユーザーのidリスト delete_target_id = search_list_id_list[delete_target_id_number] # 個別ユーザーのidリスト中、削除するid json_load_list_id_list = [d.get('id') for d in json_load_list] # 全ユーザーのidリスト delete_id_number = json_load_list_id_list.index(delete_target_id) # 全ユーザーのidリスト中、削除するidが何番目に存在するか # pay_manager.delete_pay(number) #--- 修正前 pay_manager.delete_pay(delete_id_number) #--- 修正10-2 # JSONファイルに書き込み --- 修正7 with open(file_path, mode='w',encoding="UTF-8") as open_json: updated_data_list=[] for pay in pay_manager.pay_data_list: updated_data_list.append({ "month" : pay.month, "day" : pay.day, "content" : pay.content, "amount" : pay.amount, "id" : pay.id , # --- 追加10-2 "user" : pay.user # --- 追加10 }) json.dump(updated_data_list, open_json ,indent=4,ensure_ascii=False) updated_search_list = [ item for item in updated_data_list if item['user'] == user_name ] #--- 追加10 # 更新した辞書型リストを送信し、HTMLをレンダリング # return render_template('kakeibo_test_json/kd.html', title='kakeibo', pay_list=pay_manager.pay_data_list) #--- 修正7-4 '''修正前''' return render_template('kakeibo_test_json/kd.html', title='kakeibo',user_name = user_name , pay_list = updated_search_list ) #--- 修正10 # ------------------------------------------------------------------------------ # #### HTTPリクエスト ####   POSTメソッド受信 ####  「送信」 ボタンが押されたときの処理 # --- 追加6-2 if request.method == 'POST': # 画面上で入力された情報を取得し、辞書データを作成 add_dict = {"month" : request.form.get('month'), "day" : request.form.get('day'), "content" : request.form.get('content'), "amount" : request.form.get('amount'), "id" : main_key , # --- 追加10-2 "user" : user_name # --- 追加10 } # 辞書データを辞書型リスト(PayManagerオブジェクト)に追加 pay_manager.add_pay(add_dict) #--- 修正7-5 (前)  json_load_list.append(add_dict) # JSONファイルに書き込み # --- 修正7-6 with open(file_path, mode='w',encoding="UTF-8") as open_json: updated_data_list=[] for pay in pay_manager.pay_data_list: updated_data_list.append({ "month" : pay.month, "day" : pay.day, "content" : pay.content, "amount" : pay.amount, "id" : pay.id, # --- 追加10-2 "user" : pay.user # --- 追加10 }) json.dump(updated_data_list, open_json ,indent=4,ensure_ascii=False) updated_search_list = [ item for item in updated_data_list if item['user'] == user_name ] #--- 追加10 # 更新した辞書型リストを送信し、HTMLをレンダリング # return render_template('kakeibo_test_json/kd.html', title='kakeibo', pay_list=pay_manager.pay_data_list)# 修正7-4 '''修正前'''''' return render_template('kakeibo_test_json/kd.html', title='kakeibo',user_name = user_name , pay_list = updated_search_list ) #--- 修正10 # ------------------------------------------------------------------------------ # # # ------------------------------------------------------------------------------ # if __name__ == '__main__': app.run()
■■

このブログを検索

アーカイブ

カテゴリー

QooQ