59753


**実現したいこと**

フォームに入力した文字列がデータベースに格納され、HTMLのページに反映されるプログラムをPython・FlaskとSQLAlchemyを使って書いています。

**困っていること**

[code]

    $ FLASK_APP=app.py FLASK_DEBUG=true flask run
    
[/code]

上記のコマンドで、現行のコードをブラウザで実行すると、フォーム画面は表示されるのですが、フォームに文字列を記入し送信すると以下のエラーが出ます。

エラー文（書いたプログラム以外のファイルに関する、実行後レスポンスの記述は省略しています）

[code]

    File "/Users/username/Desktop/app.py", line 32, in create_todo print(sys.exc_infor())
    NameError: name 'sys' is not defined
    
[/code]

**試したこと**  
`import sys`とプログラム頭に追記したところ、以下のようにエラーが変化しました。  
いずれにしても、解決策が分からず困っています。

[code]

    File "/Users/username/Desktop/app.py", line 32, in create_todo print(sys.exc_infor())
    AttributeError: module 'sys' has no attribute 'exc_infor'
    
[/code]

実行しているプログラム  
index.html

[code]

    <html>
    <head>
        <title>Todo App</title>
    <style>
        .hidden{
            display:  none;
        }
    </style>
    </head>
    <body>
        <form method="post" action="/todos/create">
            <input type= "text" name="description" />
            <input type= "submit" value="Create" />
        </form>
        <div id= "error" class="hidden">Something went wrong!</div>
        <ul>
            {% for d in data %}
            <li>{{d.description}}</li>
            {% endfor %}
        </ul>
        <script>
          const descInput = document.getElementById('description');
          document.getElementById('form').onsubmit = function(e) {
            e.preventDefault();
            const desc = descInput.value;
            descInput.value = '';
            fetch('/todos/create', {
              method: 'POST',
              body: JSON.stringify({
                'description': desc,
              }),
              headers: {
                'Content-Type': 'application/json',
              }
            })
            .then(response => response.json())
            .then(jsonResponse => {
              console.log('response', jsonResponse);
              li = document.createElement('li');
              li.innerText = desc;
              document.getElementById('todos').appendChild(li);
              document.getElementById('error').className = 'hidden';
            })
            .catch(function() {
              document.getElementById('error').className = '';
            })
          }
        </script>
    </body>
    </html>
    
[/code]

app.py

[code]

    from flask import Flask, render_template, request, redirect, url_for, abort
    from flask_sqlalchemy import SQLAlchemy
    #import sys
    
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://username@localhost:5432/todoapp'
    db = SQLAlchemy(app)
    
    class Todo(db.Model):
        __tablename__ = 'todos'
        id = db.Column(db.Integer, primary_key=True)
        description = db.Column(db.String(), nullable=False)
    
        def __repr__(self):
            return f'<Todo {self.id}{self.description}>'
    
    db.create_all()
    
    @app.route('/todos/create', methods=['POST'])
    def create_todo():
        error = False
        body = {}
        try:
            description = request.form.get_json()['description']
            todo = Todo(description=description)
            db.session.add(todo)
            db.session.commit()
            body['description'] = todo.description
        except:
            error = True
            db.session.rollback()
            print(sys.exc_infor())
        finally:
            db.session.close()
        if error:
            abort(400)
        else:
            return jsonify(body)
    
    @app.route('/')
    def index():
        return render_template('index.html', data=Todo.query.all())
    
[/code]

実行環境  
Flask 1.1.1  
sqlalchemy 1.3.10


CC BY-SA 4.0
2019-10-16T23:41:53.083
59752
2019-10-17T03:57:22.263
question
python json flask sqlalchemy url-routing
Flaskで作ったフォームに文字列を入力するとルーティングがうまくいかない


> AttributeError: module 'sys' has no attribute 'exc_infor'

タイポだと考えられます。  
<https://docs.python.org/2/library/sys.html#sys.exc_info>

ダメ: `exc_infor`  
良い: `exc_info`

その他にエラーが出るなら、以下を試してください。

import文にjsonifyのインポート部分を追加してください。

[code]

    from flask import Flask, render_template, request, redirect, url_for, abort, jsonify
    
[/code]

さらに、formからget_jsonを消し、代わりに直接キーを指定するようにします。

[code]

    description = request.form['description']
    
[/code]

コードのappの初期化コードの下に

[code]

    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    
[/code]

を追加してください。

postgresqlで動作がしなければ、postgresqlの設定を確認するか、実行確認のためにsqliteに変更してみてください。

[code]

    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
    
[/code]


CC BY-SA 4.0
2019-10-16T23:48:10.610
59753
2019-10-17T03:57:22.263
2019-10-17T03:57:22.263
59752
answer