我正在使用peewee作为ORM创建一个API,我需要将peewee模型对象转换成JSON对象并发送给用户。有没有好的方法可以做到这一点?
Peewee在playhouse.shortcuts
扩展模块中提供了model_to_dict
和dict_to_model
助手。
您可以按以下方式使用它们:
from playhouse.shortcuts import model_to_dict, dict_to_model
user_obj = User.select().where(User.username == 'charlie').get()
json_data = json.dumps(model_to_dict(user_obj))
请注意,model_to_dict()
可以递归处理相关模型,包括被反向引用的模型,并排除某些字段不被序列化。
model_to_dict()
? - Zaaferanifrom playhouse.shortcuts import *
- Michael Dornerfrom playhouse.shortcuts import model_to_dict, dict_to_model
- ArelSelectQuery
对象上以这种方式使用model_to_dict
(即不使用.get()
)?我要么看到一个错误消息,如'SelectQuery' object has no attribute '_meta'
,要么如果表包含UUID字段,则会看到Object of type 'UUID' is not JSON serializable
。 - AdjunctProfessorFalconimport json; import uuid; x = uuid.uuid4(); json.dumps(x);
Traceback (most recent call last): ... TypeError: Object of type 'UUID' is not JSON serializable
- dingus9user = User.select().where(User.id == 1).get()
model_to_dict(user) #to Dict
users = list(User.select().where(User.name ** 'a%').dicts())
import peewee
import json
from bson import json_util
from datetime import datetime
class User(peewee.Model):
email = CharField()
status = BooleanField(default=True)
firstname = CharField()
lastname = CharField()
age = IntegerField()
created = DateTimeField(default=datetime.now())
class Meta:
database = db
user = User.select().dicts().get()
print json.dumps(user, default=json_util.default)
created = DateTimeField()
,那么json.dumps(user)会报告datetime.datetime实例无法序列化为JSON。在这种情况下,我该如何处理datetime字段? - Roland Pish`from bson import json_util`
`print json.dumps(user, default=json_util.default)`
- kiba'{"born": {"$date": 1399579518000}, "name": "John Smith"}'
的东西。而尝试使用这个:https://pypi.python.org/pypi/bson/0.3.3 则导致应用程序崩溃。不过还是谢谢你的提示。 - Roland Pish对于遇到类似 TypeError: Object of type date is not JSON serializable
的问题,这是我的解决方案(在 Python 3.8.2 上测试通过)。
from playhouse.shortcuts import model_to_dict
import json
def print_model(model):
print(json.dumps(model_to_dict(model), indent=4, sort_keys=True, default=str))
def print_models(models):
print(json.dumps(list(models.dicts()), indent=4, sort_keys=True, default=str))
用法1 - 单个模型
for person in Person.select():
print_model(person)
用法2 - 多个模型
print_models(Person.select())
from decimal import Decimal
import datetime
try:
import uuid
_use_uuid = True
except ImportError:
_use_uuid = False
datetime_format = "%Y/%m/%d %H:%M:%S"
date_format = "%Y/%m/%d"
time_format = "%H:%M:%S"
def set_datetime_format(fmt_string):
datetime_format = fmt_string
def set_date_format(fmt_string):
date_format = fmt_string
def set_time_format(fmt_string):
time_format = fmt_string
def more(obj):
if isinstance(obj, Decimal):
return str(obj)
if isinstance(obj, datetime.datetime):
return obj.strftime(datetime_format)
if isinstance(obj, datetime.date):
return obj.strftime(date_format)
if isinstance(obj, datetime.time):
return obj.strftime(time_format)
if _use_uuid and isinstance(obj, uuid.UUID):
return str(obj.db_value())
raise TypeError("%r is not JSON serializable" % obj)
import json
from utils import json_serialize
...
json.dumps(model_to_dict(User.get()), default=json_serialize.more)
编辑以添加:这主要受到mongodb中发现的json_utils.default
模块的启示,但主要依赖于json
模块,不需要导入mongodb自己的bson / json_utils模块。
通常,我会在应用程序引发TypeError
未能序列化的类型时立即更新它以支持新类型。
我通常实现模型到字典和字典到模型的函数,以获得最大的安全性和对代码内部工作的理解。Peewee做了很多魔法,你希望能够控制它。
明显的原因是为什么你不应该在字段上进行迭代而是明确指定它们,这是出于安全考虑。并非所有字段都可以暴露给用户,我假设你需要这个功能来实现某种REST API。
所以 - 你应该像这样做:
class UserData(db.Model):
user = db.ForeignKeyField(User)
data = db.CharField()
def serialize():
# front end does not need user ID here
return {
'data': self.data
}
@classmethod
def from_json(cls, json_data):
UserData.create(
# we enforce user to be the current user
user=current_user,
data=json_data['data']
)
class MyModel(peewee.Model):
def __str__(self):
r = {}
for k in self._data.keys():
try:
r[k] = str(getattr(self, k))
except:
r[k] = json.dumps(getattr(self, k))
return str(r)
class User(MyModel):
email = CharField()
status = CharField(default="enabled")
firstname = CharField()
lastname = CharField()
class Meta:
database = db
json.dumps(str(user))
而不是 json.dumps(user)
。 - Matthew Moisenmodel_to_dict()
助手,它专门为此目的而设计。您可以在这里找到文档(http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#model_to_dict)。它还有一个好处,就是能够递归或排除字段。 - coleifer