私は、peeweeをORMとして使用してAPIを作成しています。peeweeモデルオブジェクトをJSONオブジェクトに変換してユーザーに送信する機能が必要です。これを行うための良い方法を誰かが知っていますか?
Peeweeは、_model_to_dict
_拡張モジュールに_dict_to_model
_および_playhouse.shortcuts
_ヘルパーを備えています。
これらは次のように使用できます。
_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()
は、関連するモデルを再帰し、後方参照モデルを含め、特定のフィールドをシリアル化から除外できることに注意してください。
また、dictとしてモデルを取得し、正しいフィールドタイプ(bool、int、floatなど)でjsonに変換することもできます。
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)
私はこれと同じ問題を抱えており、自動的にシリアル化できないJSON型の独自のパーサー拡張を定義することになりました。今のところ、表現されるデータとして文字列を使用することに問題はありません(さまざまなデータ型を使用できる可能性がありますが、浮動小数点を使用した近似に注意してください!)
次の例では、これをutils
フォルダー内のjson_serialize.py
というファイルに入れます。
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
を発生させてシリアル化できない型を見つけたらすぐに、新しい型をサポートするように更新します
私は通常、最大限のセキュリティとコードの内部動作の理解のために、dict to dictとdict to model関数を実装します。 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']
)