Flask TypeError: аргумент типа «NoneType» не является итерируемым

Я не уверен, почему я получаю эту ошибку TypeError:

Файл «C:/Users/PycharmProjects/REST/app.py», строка 30, в объекте valid_book_object if («isbn» в книге и «имя» в книге и «цена» в книге): TypeError: аргумент типа «NoneType» не повторяется 127.0.0.1 - - [12/ноября/2018 14:22:29] "POST /books HTTP/1.1" 500 -

Код:

from flask import Flask, jsonify, request
from test import *
app=Flask(__name__)

books=[
    {'name': 'M',
     'price': 6.75,
    'isbn':123
    },
    {'name': 'G',
     'price': 7.75,
    'isbn':456
    },

]


#GET /store
@app.route('/books')  #first endpoint
def get_books():
    return jsonify({'books': books})

# POST /books
#{'name': 'F',
 #'price': 7.00,
 #'isbn': 789
 #},

def valid_book_object(book):
    if ("isbn" in book and "name" in book and "price" in book):
         return True
         print("true")
    else:
        return False
        print("false")


@app.route('/books', methods=['POST'])
def add_book():
    #return jsonify(request.get_json())
     request_data=request.get_json()
     if(valid_book_object(request_data)):
        books.insert(0, request_data)
        return "True"
     else:
        return "False"


#GET /books/456
@app.route('/books/<int:isbn>')  #second endpoint
def get_book_by_isbn(isbn):
    return_value={}
    for book in books:
        if book["isbn"]==isbn:
            return_value={
                'name': book["name"],
                'price':book["price"]
            }
    return jsonify(return_value)



app.run(port=5000)

person LPGA    schedule 12.11.2018    source источник
comment
book имеет значение None. Поэтому, когда вы пытаетесь выполнить "isbn" in book, предполагается, что book является итерируемым, но вместо этого оказывается None, который не является итерируемым. Об этом говорит сообщение об ошибке.   -  person Eskapp    schedule 13.11.2018
comment
Обязательно ли определять класс книги?? books используется в качестве аргумента в коде.   -  person LPGA    schedule 13.11.2018
comment
Это не связано с тем, есть класс или нет. Это связано со значением (None), которое может принимать переменная book и которое не обрабатывается в коде. Вы проверяли, является ли request_data пустым файлом json или нет, когда возникает ошибка.   -  person Eskapp    schedule 13.11.2018


Ответы (1)


Вы не отправляете данные JSON на маршрут /books методом POST.

Я попробовал ваше решение с почтальоном, и оно сработало. Кроме того, если вы хотите использовать какой-либо маршрут для GET и POST, не разделяйте их. Используйте methods=['GET', 'POST']. Вот ваш код, переформатированный по стандарту PEP 8:

from flask import Flask, jsonify, request

app = Flask(__name__)

books = [
    {'name': 'M',
     'price': 6.75,
     'isbn': 123
     },
    {'name': 'G',
     'price': 7.75,
     'isbn': 456
     }
]

# POST /books
# {
#     "name": "F",
#     "price": 7.00,
#     "isbn": 789
# }


def valid_book_object(book):
    if "isbn" in book and "name" in book and "price" in book:
        return True
    else:
        return False


@app.route('/books', methods=['GET', 'POST'])
def add_book():
    # If request is GET, just return JSON data of books.
    if request.method == 'GET':
        return jsonify({'books': books})
    else:
        # This is part if it is POST request
        request_data = request.get_json()
        if valid_book_object(request_data):
            books.insert(0, request_data)
            return "True"
        else:
            return "False"


# GET /books/456
@app.route('/books/<int:isbn>')  # second endpoint
def get_book_by_isbn(isbn):
    return_value = {}
    for book in books:
        if book["isbn"] == isbn:
            return_value = {
                'name': book["name"],
                'price': book["price"]
            }
            return jsonify(return_value)
    return 'No book with {} isbn value'.format(isbn)


if __name__ == '__main__':
    app.run(port=5000)

А вот вывод postman (вы можете увидеть True внизу, это то, что вы возвращаете, если POST прошел успешно):

почтальон

Если вы используете почтальон, обязательно выберите application/json тип контента.

Если вы используете метод JQuery ajax, прочтите этот ответ. Но в любом случае, здесь используется JQuery (проверено):

data = JSON.stringify({
    name: "F",
    price: 7.00,
    isbn: 789
});
$.ajax({
  url: '/books',
  type: "POST",
  data: data,
  contentType: "application/json",
  dataType: "json",
  success: function(){
    console.log('Post executed successfully');
  }
})
person Dinko Pehar    schedule 22.11.2018