質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1100閲覧

【Flask】一対多のデータベースから親のuser_idの取得が出来ません。

pochidog

総合スコア15

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/07/18 07:38

実現したいこと

現在Flaskにて管理画面の作成を行なっております。
管理画面にて「お知らせ」を投稿した際に、current_userのidを取得してNewsテーブルに紐付けて格納したいのですが、上手く出来ません。

printにて確認したところ、current_user.id自体は取得出来ているようなのですが、<User 1>ではなく、user_idのみを取得するにはどのように指定すると良いでしょうか。。

補足情報(FW/ツールのバージョンなど)

・macOS Monterey : 12.4
・amazon liunx2 : t2.micro
・Python : 3.7.10
・Flask : 2.1.2
・Flask-SQLAlchemy : 2.5.1
・SQLAlchemy : 1.4.39

階層構造

  • project名/
    • app.py
    • database.py
    • config.py
    • views/
      • project名_view.py
    • models/
      • init.py
      • models.py
    • templates/
    • static/

発生している問題・エラーメッセージ

<User 1> # ↑printにてcurrent_user.idを出力しております。 sqlalchemy.exc.DataError: (pymysql.err.DataError) (1366, "Incorrect integer value: '<User 1>' for column 'user_id' at row 1") [SQL: INSERT INTO news (title, start_on, registered_date, content, user_id) VALUES (%(title)s, %(start_on)s, %(registered_date)s, %(content)s, %(user_id)s)] [parameters: {'title': 'サンプルタイトル', 'start_on': '2022-07-18T16:00', 'registered_date': datetime.datetime(2022, 7, 18, 7, 6, 40, 325065), 'content': 'TestText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText_SampleText', 'user_id': <User 1>}] (Background on this error at: https://sqlalche.me/e/14/9h9h)

該当のソースコード

app.py

1from flask import Flask 2from views import project名_view 3from database import db, login_manager 4import os 5import models 6import config 7 8def create_app(): 9 app = Flask(__name__) 10 11 app.config.from_object('config.Config') 12 app.config['SECRET_KEY'] = os.urandom(24) 13 db.init_app(app) 14 login_manager.init_app(app) 15 16 app.register_blueprint(project名_view.app) 17 return app 18 19app = create_app() 20 21with app.app_context(): 22 db.create_all() 23 24if __name__ == "__main__": 25 app.run(host='0.0.0.0', debug=True)

views/project名_view.py

1from flask import Blueprint, render_template, request, redirect, url_for, session 2from flask_login import current_user 3from werkzeug.security import generate_password_hash, check_password_hash 4from database import db, login_manager, login_user, logout_user, login_required 5from models import Contact, User, News 6import datetime 7 8app = Blueprint('views', __name__) 9 10# 中略 11 12@app.route('/news_create', methods=['GET', 'POST']) 13def news_create(): 14 if request.method == 'POST': 15 title = request.form.get('title') 16 start_on = request.form.get('start_on') 17 registered_date = datetime.datetime.now() 18 content = request.form.get('content') 19 user_id = User.query.get(current_user.id) 20 print(user_id) 21 news = News(title=title, start_on=start_on, registered_date=registered_date, content=content, user_id=user_id) 22 db.session.add(news) 23 db.session.commit() 24 return redirect('/admin') 25 else: 26 title = "プロジェクト名|お知らせ投稿" 27 return render_template('admin_news_create.html', title=title)

templates/admin_news_create.html

1{% extends 'application.html' %} 2 3{% block body %} 4<section class="admin"> 5 {% include 'admin_nav.html' %} 6 <div class="right_content"> 7 {% include 'admin_header.html' %} 8 9 <div class="admin_contents"> 10 <div class="admin_title"> 11 <h2>お知らせ投稿</h2> 12 <form id="admin_news_form" method="POST" action="/news_create"> 13 <div class="admin_news_form"> 14 <label>タイトル<span class="mandatory">必須</span></label><br> 15 <input type="text" name="title" placeholder: "最大入力20文字"> 16 </div> 17 18 <div class="admin_news_form news_edit_form admin_news_date"> 19 <label>掲載開始日<span class="mandatory">必須</span></label><br> 20 <input type="datetime-local" name="start_on"> 21 </div> 22 23 <div class="admin_news_form"> 24 <label>お知らせ詳細<span class="mandatory">必須</span></label><br> 25 <input type="text" name="content"> 26 </div> 27 <div class="admin_news_submit"> 28 <input type="submit" value="投稿"> 29 </div> 30 </form> 31 </div> 32 </div> 33 34 {% include 'admin_footer.html' %} 35 </div> 36</section> 37{% endblock %}

models/models.py

1from database import db, UserMixin 2import datetime 3 4# 中略 5 6class User(UserMixin, db.Model): 7 __tablename__ = 'users' 8 id = db.Column(db.Integer, primary_key=True) 9 user_name = db.Column(db.String(30), nullable=True, unique=True) 10 email = db.Column(db.String(300), nullable=True, unique=True) 11 password = db.Column(db.String(300), nullable=True) 12 password_confirmation = db.Column(db.String(300), nullable=True) 13 first_name = db.Column(db.String(30), nullable=True) 14 last_name = db.Column(db.String(30), nullable=True) 15 news = db.relationship('News', backref='users') 16 17class News(db.Model): 18 __tablename__ = 'news' 19 id = db.Column(db.Integer, primary_key=True) 20 title = db.Column(db.String(60), nullable=True, unique=True) 21 start_on = db.Column(db.DateTime, nullable=True) 22 registered_date = db.Column(db.DateTime, default=datetime.datetime.utcnow) 23 content = db.Column(db.Text, nullable=True) 24 user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

試したこと

current_user.idを取得できるように、様々なサイトを参考に試行錯誤しているのですが、解決にはいたりませんでした。
指定方法によっては投稿した際にエラーが出ず、投稿できるのですが、Newsテーブルのuser_idがNULLになってしまいます。
上記の提示しているコードが一番解決に近いのですが、後一歩のところで苦戦しております。。
※user_idを取得せず(一対多の関係にしなかった場合)投稿した際には、問題なく投稿は出来ている状態でした。

本件、お分かりの方がいらっしゃいましたらご教授頂けますと幸いです。
その他に必要な情報等がありましたら提示いたします。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Flask-Loginのcurrent_userのことですよね?
「一対多のデータベースから親のuser_idの取得が出来ません。」というタイトルですが、DB設計の前にflask-loginの使い方が正しく無いような気がするのでとりあえずそちらについて書きます。

Login Example

上記に記載があるように、current_userはログインしたユーザにアクセスできるようになるものです。
login_user(user)のような感じでログインが必要なのですが、実施済みでしょうか?

また、userクラスにはいくつかメソッドが必要です。
それはこちら(Your User Class)に記載がありますが、実装済みでしょうか?

さらに、ログインが必須のページは以下の様な@login_requiredが付いている関数で作成可能ですが、無い場合はログインされていない場合もアクセスでき、current_userが存在しない可能性がありますが、ログイン済みであることは確定されている場所で試していますでしょうか?

python

1@app.route("/settings") 2@login_required 3def settings(): 4 pass

投稿2022/07/19 00:55

FiroProchainezo

総合スコア2392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pochidog

2022/07/19 10:53

@FiroProchainezo様 ご回答頂きありがとうございます。 > Flask-Loginのcurrent_userのことですよね? はい、ご認識の通りです。 > DB設計の前にflask-loginの使い方が正しく無いような気がするのでとりあえずそちらについて書きます。 なるほどですね。。 確かにおっしゃる通り、flask-loginは試行錯誤しながら開発しておりましたので、正しくない箇所はあるかと思います。リンクを貼っていただいたflask-loginのサイトを再度確認してみたいと思います。 > さらに、ログインが必須のページは以下の様な@login_requiredが付いている関数 こちらは、上記の「def news_create():」の箇所は記載しておりませんでしたが、そのほかのログインが必須のページについては記載出来ております。 ただ、「def news_create():」の箇所にも記載は必要ですので、記載いたします。 > current_userが存在しない可能性がありますが、ログイン済みであることは確定されている場所で試していますでしょうか? こちらについては、確認する際にログインするところから確認しておりますので、ログイン済みの状態で確認は出来ております。 ご教授、ご指摘頂きありがとうございます。 頂いたリンクを確認し、再度試してみたいと思います。
guest

0

自己解決

本件の一対多のデータベースから親のuser_idの取得出来ない件ですが、自己解決いたしました。
そもそも記述方法が間違えておりました。(理解不足です。。)

▼本件解決前

views/project名_view.py

1user_id = User.query.get(current_user.id) 2 print(user_id) 3 news = News(title=title, start_on=start_on, registered_date=registered_date, content=content, user_id=user_id)

上記の1行目ですが、User.query.getにてcurrent_userのidを取得する記述は要らず、3行目のようにuser_id=current_user.idと記述することで、誰が投稿したデータなのかという親のuser_idを取得できました。

▼本件解決後

views/project名_view.py

1 news = News(title=title, start_on=start_on, registered_date=registered_date, content=content, user_id=current_user.id)

試行錯誤での解決になりますので、こちらの実装方法はおかしいという場合やもっと適切な実装方法があるようでしたらご教授頂けますと幸いです。

投稿2022/07/29 13:06

編集2022/07/29 13:08
pochidog

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問