[英]Flask API throws TypeError: Object of type is not JSON serializable
I am building a Flask API w/a Postgresql db.我正在构建一个 Flask API w/a Postgresql db。 I have two main models, Contacts and Outlets with a many-to-many association.
我有两个主要模型,Contacts 和 Outlets 具有多对多关联。 Everything works fine until I attempt to use the association to return the outlets for a given contact.
一切正常,直到我尝试使用关联返回给定联系人的出口。 I am using flask-sqlalchemy as an ORM. The route below aimed at retrieving a single contact throws:
TypeError: Object of type Outlet is not JSON serializable
我正在使用 flask-sqlalchemy 作为 ORM。下面的路线旨在检索单个联系人抛出:
TypeError: Object of type Outlet is not JSON serializable
@contacts.get("/<int:id>")
@jwt_required()
def get_contact(id):
contact = Contact.query.filter_by(id=id).first()
print('contact-outlets are: ', contact.outlets[0])
if not contact:
return jsonify({'message':'Item not found'}), HTTP_404_NOT_FOUND
return jsonify({
'id':contact.id,
'name':contact.name,
'email':contact.email,
'bio':contact.bio,
'image_url':contact.image_url,
'outlets':contact.outlets,
'created_at':contact.created_at,
'updated_at':contact.updated_at,
}), HTTP_200_OK
Here is the relevant portion of the database schema if it helps:如果有帮助,这里是数据库模式的相关部分:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from sqlalchemy.orm import relationship
db = SQLAlchemy()
class Contact(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
bio = db.Column(db.Text, nullable=True)
image_url = db.Column(db.Text)
visits = db.Column(db.Integer, default=0)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
created_at = db.Column(db.DateTime, default=datetime.now())
updated_at = db.Column(db.DateTime, onupdate=datetime.now())
calls = db.relationship("Call", backref="call_contact", lazy="joined")
outlets = db.relationship("Outlet", secondary="contact_outlet", backref="contact", lazy="joined")
def __repr__(self) -> str:
return 'Contact>>> {self.name}'
class Outlet(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
website = db.Column(db.Text)
description = db.Column(db.Text)
image_url = db.Column(db.Text)
created_at = db.Column(db.DateTime, default=datetime.now())
updated_at = db.Column(db.DateTime, onupdate=datetime.now())
calls = db.relationship("Call", backref="outlet", lazy="joined")
contacts = db.relationship("Contact", secondary="contact_outlet", lazy="joined")
def __repr__(self) -> str:
return 'Outlet>>> {self.name}'
def to_json(self):
return {
"id": self.id,
"name": self.name,
"website": self.website,
"description": self.description,
"image_url": self.image_url,
"contacts": self.contacts
}
contact_outlet = db.Table('contact_outlet',
db.Column('contactId', db.Integer, db.ForeignKey("contact.id"), primary_key=True),
db.Column('outletId', db.Integer, db.ForeignKey("outlet.id"), primary_key=True)
)
The error is direct, that you have values that are not JSON ready in your response.错误是直接的,您的响应中没有准备好 JSON 的值。
You have an item in your dict, 'outlets':contact.outlets,
, which is ideally a list of Outlet
objects as per your model definition.您的字典中有一个项目
'outlets':contact.outlets,
,根据您的 model 定义,它是理想的Outlet
对象列表。 You need to tell flask-jsonify
, how to make that object a JSON你需要告诉
flask-jsonify
,如何使 object 成为 JSON
In a normal json.dumps
operation, you can do this by passing a custom encoder or default method.在正常的
json.dumps
操作中,您可以通过传递自定义编码器或默认方法来完成此操作。 You can do this, by setting the encoder option in flask.您可以通过在 flask 中设置编码器选项来做到这一点。
First, you create a custom model encoder for JSON. An example could be like below首先,您为 JSON 创建一个自定义 model 编码器。示例如下所示
from flask import json
class ModelEncoder(json.JSONEncoder):
def default(self, o: Any) -> Any:
if hasattr(o, 'to_json'):
return o.to_json()
else:
return super(ModelEncoder, self).default(o)
And now, ask flask to use this encoder for converting models to JSON. For this you can set the flask app configuration.现在,要求 flask 使用此编码器将模型转换为 JSON。为此,您可以设置 flask 应用程序配置。
app.json_encoder = ModelEncoder
If you have a to_json
method in your model, it will call that for serializing those.如果您的 model 中有一个
to_json
方法,它将调用该方法来序列化这些方法。 Other wise it follows the default.否则它遵循默认值。 Yes, this is a simple implementation, you can improvise with type checks or variations.
是的,这是一个简单的实现,您可以通过类型检查或变体即兴创作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.