【问题标题】:How to solve TypeError: Object of type 'Category' is not JSON serializable如何解决 TypeError:“类别”类型的对象不是 JSON 可序列化的
【发布时间】:2020-06-26 21:06:53
【问题描述】:

我有 3 个表(书籍、作者、类别)

当我尝试获取书籍或作者列表时,出现以下错误:TypeError: 'Category' 类型的对象不是 JSON 可序列化的。我认为这与与类别表的关系有关。请检查我的模型是否结构良好,我该如何解决这个问题。

__tablename__ = 'author'
id = db.Column(db.Integer().with_variant(Integer, "sqlite"), primary_key=True)
auth_nam = db.Column(db.String, nullable=False)
gender = db.Column(db.String, nullable=True)
count_book = db.Column(db.Integer,nullable=False)
category=db.relationship('Category', backref='author', lazy=True)

def __init__(self,auth_nam,gender,count_book,category):
  self.auth_nam = auth_nam
  self.gender = gender
  self.count_book = count_book
  self.category = category

def insert(self):
  db.session.add(self)
  db.session.commit()

def update(self):
  db.session.commit()

def delete(self):
  db.session.delete(self)
  db.session.commit()

def format(self):
  return {
    'id': self.id,
    'auth_nam': self.auth_nam,
    'gender': self.gender,
    'count_book': self.count_book,
    'category': self.category
  }

'''
Books
'''
class Book(db.Model):
__tablename__='book'
id = db.Column(db.Integer().with_variant(Integer, "sqlite"), primary_key=True)
book_name=db.Column(db.String,nullable=False)
book_issue=db.Column(db.DateTime,nullable=False)
category=db.relationship('Category', backref='book', lazy=True)

def __init__(self, book_name, book_issue, category):
   db.create_all()
   self.book_name = book_name
   self.book_issue = book_issue
   self.category = category

def insert(self):
  db.session.add(self)
  db.session.commit()

def update(self):
  db.session.commit()

def delete(self):
  db.session.delete(self)
  db.session.commit()

def format(self):
  return {
    'id': self.id,
    'book_name': self.book_name,
    'book_issue': self.book_issue,
    'category': self.category,
  }


'''
Category
'''
class Category(db.Model):
__tablename__ = 'category'
id = Column(db.Integer, primary_key=True)
name = Column(db.String,nullable=False)
book_id = db.Column(db.Integer, db.ForeignKey('book.id'),nullable=False)
author_id = db.Column(db.Integer, db.ForeignKey('author.id'),nullable=False)

def __init__(self, name, book_id, author_id):
  self.name = name
  self.book_id = book_id
  self.author_id = author_id

def insert(self):
  db.session.add(self)
  db.session.commit()

def update(self):
  db.session.commit()

def delete(self):
  db.session.delete(self)
  db.session.commit()

def format(self):
  return {
    'id': self.id,
    'name': self.name,
    'book_id': self.book_id,
    'author_id': self.author_id,
  }


def format(self):
  return {
    'id': self.id,
    'book_name': self.book_name,
    'book_issue': self.book_issue,
    'category': self.category,
  }


'''
Category
'''
class Category(db.Model):
__tablename__ = 'category'
id = Column(db.Integer, primary_key=True)
name = Column(db.String,nullable=False)
book_id = db.Column(db.Integer, db.ForeignKey('book.id'),nullable=False)
author_id = db.Column(db.Integer, db.ForeignKey('author.id'),nullable=False)

def __init__(self, name, book_id, author_id):
  self.name = name
  self.book_id = book_id
  self.author_id = author_id

def insert(self):
  db.session.add(self)
  db.session.commit()

def update(self):
  db.session.commit()

def delete(self):
  db.session.delete(self)
  db.session.commit()

def format(self):
  return {
    'id': self.id,
    'name': self.name,
    'book_id': self.book_id,
    'author_id': self.author_id,
  }

app.py:

 @app.route('/books', methods=['GET'])
  def get_books():
    books = Book.query.all()
    books_formated=[book.format() for book in books]
    return jsonify({
       "success": True,
       "books":books_formated
    })

【问题讨论】:

  • 您错误地发布了两次类别模型还是您的代码中的错误?

标签: api flask flask-sqlalchemy


【解决方案1】:

由于您已将 category 设置为 Book 模型上的关系属性,因此当您在 Book.format() 中调用此行时:

'category': self.category

self.category 将返回相关的Category 实例,它是一个 Python 对象。但是,Python 对象不是 JSON 可序列化的,这就是为什么在调用 jsonify() 时会得到 TypeError: Object of type 'Category' is not JSON serializable.

要解决这个问题,您可以将self.category 更改为'category': [category.name for category in self.category](获取类别名称的字符串)或'category': [category.format() for category in self.category](获取类别数据的字典)。 string 和 dict 都是 JSON 可序列化的。

【讨论】:

  • 我将模型编辑为``` def format(self): return { 'id': self.id, 'book_name': self.book_name, 'book_issue': self.book_issue, 'category ': self.category.name, } ``` 我得到这个错误:AttributeError: 'InstrumentedList' object has no attribute 'name'
  • 那是因为书可以有多个分类(之前没注意),你可以试试这个:'category': [category.name for category in self.category]
猜你喜欢
  • 2017-09-05
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
  • 2019-11-21
  • 2021-11-13
  • 2018-09-22
  • 2019-01-17
相关资源
最近更新 更多