flask python 3 TypeError («Объект« NoneType »не может быть подписан») - PullRequest
0 голосов
/ 03 мая 2020

Я работаю над примером проекта для курса и получаю сообщение об ошибке:

TypeError("'NoneType' object is not subscriptable"

, и в моем браузере я вижу:

Bad Request Браузер (или прокси) отправил запрос, который этот сервер не может понять.

Я не знаю, что я делаю здесь не так. Я использую flask, sqlalchemy, postgresql и python 3, и я не могу понять, что происходит не так. Это мой код:

app.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)

index. 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>

1 Ответ

2 голосов
/ 03 мая 2020

Вы не указали свой идентификатор формы.

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

Я нашел эту проблему, используя инструменты разработчика, о которых упоминал @snakecharmerb.

Затем вы пытались получить доступ к 'description' как будто jsonResponse была функцией. Поскольку это JSON, вам нужны квадратные скобки вокруг описания: ['description'].

                .then(response => {
                    return response.json()
                })
                .then(jsonResponse => {
                    let liItem = document.createElement('li');
                    liItem.innerHTML = jsonResponse['description'];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...