首页 > 解决方案 > flask python 3 TypeError(“'NoneType'对象不可下标”

问题描述

我正在为一门课程开发一个示例项目并收到错误消息:

TypeError("'NoneType' object is not subscriptable"

在我的浏览器中,我正在搜索:

错误请求 浏览器(或代理)发送了此服务器无法理解的请求。

我不知道我在这里做错了什么。我正在使用烧瓶、sqlalchemy、postgresql 和 python 3,但我不知道出了什么问题。这是我的代码:

应用程序.py:

#!/usr/bin/python3

from flask_sqlalchemy import SQLAlchemy
from flask import Flask, render_template, request, redirect, url_for, jsonify, abort
import sys

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://postgres:postgres@3.134.26.61:5432/todoapp'
db = SQLAlchemy(app)
#db = SQLAlchemy(app, session_options={"expire_on_commit": False})

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()

#todo1 = Todo(description='Todo Thing 1')
#db.session.add(todo1)
#db.session.commit()



@app.route('/')
def index():
    return render_template('index.html', data=Todo.query.all())

@app.route('/todos/create', methods=['POST'])
def create_todo():
    error = False
    body = {}
#   description = request.form.get('description', '')
#   return render_template('index.html')
    try:
        description = request.get_json()['description']
        todo = Todo(description=description)
        #body['description'] = todo.description
        db.session.add(todo)
        db.session.commit()
    except:
        error=True
        db.session.rollback()
        print(sys.exc_info())
    finally:
        db.session.close()
    if error:
        abort (400)
    else:
        return jsonify(body)
#       return jsonify({
#           'description': todo.description
#       })

#   return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

索引.html

<html>
    <head>
        <title>Todo App</title>
        <style>
            .hidden {
                display: none;
            }
        </style>
    </head>

    <body>
        <form method="POST" action="/todos/create">
            <input type="text" id="description" name="description" />
            <input type="submit" value="Create" />
        </form>
        <div id="error" class="hidden">Something went wrong</div>
        <ul id="todos">
            {% for d in data %}
                <li>{{d.description}}</li>
            {% endfor %}
        </ul>

        <script>
            document.getElementById('form').onsubmit = function(e) {
                e.preventDefault();
                userInput = document.getElementById('description').value
                fetch('/todos/create', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({'description': userInput})
                })
                .then(function(response) {
                    return response.json();
                })
                .then(function(jsonResponse){
                    console.log(jsonResponse);
                    let liItem = document.createElement('LI');
                    liItem.innerHTML = jsonResponse('description');
                    document.getElementById('todos').appendChild(liItem);
                    document.getElementById('error').className = 'hidden';
                })
                .catch(function() {
                    document.getElementById('error').className = '';
                })
            }
        </script>
    </body>

</html>

标签: pythonpostgresqlflasksqlalchemy

解决方案


你没有给你的表格一个ID。

<form method="POST" action="/todos/create" id="form">

我使用@snakecharmerb 提到的开发工具发现了这个问题。

然后你试图访问'description'好像jsonResponse是一个函数。由于它是 JSON,因此您需要在 description: 周围加上方括号['description']

                .then(response => {
                    return response.json()
                })
                .then(jsonResponse => {
                    let liItem = document.createElement('li');
                    liItem.innerHTML = jsonResponse['description'];

推荐阅读