我想在从MongoDB数据库查询时将ObjectId
和ISODate
转换为字符串表示。Mongoengine自定义查询集
def mongo_to_dict(obj, exclude_fields):
return_data = []
if obj is None:
return None
if isinstance(obj, Document):
return_data.append(("_id", str(obj.id)))
for field_name in obj._fields:
if field_name in exclude_fields:
continue
if field_name in ("id",):
continue
data = obj._data[field_name]
if isinstance(obj._fields[field_name], ListField):
return_data.append((field_name, list_field_to_dict(data)))
elif isinstance(obj._fields[field_name], EmbeddedDocumentField):
return_data.append((field_name, mongo_to_dict(data, [])))
elif isinstance(obj._fields[field_name], DictField):
return_data.append((field_name, data))
else:
return_data.append((field_name, mongo_to_python_type(obj._fields[field_name], data)))
return dict(return_data)
def list_field_to_dict(list_field):
return_data = []
for item in list_field:
if isinstance(item, EmbeddedDocument):
return_data.append(mongo_to_dict(item, []))
else:
return_data.append(mongo_to_python_type(item, item))
return return_data
def mongo_to_python_type(field, data):
if isinstance(field, DateTimeField):
return time.mktime(data.timetuple()) * 1000
elif isinstance(field, ComplexDateTimeField):
return field.to_python(data).isoformat()
elif isinstance(field, StringField):
return str(data)
elif isinstance(field, FloatField):
return float(data)
elif isinstance(field, IntField):
return int(data)
elif isinstance(field, BooleanField):
return bool(data)
elif isinstance(field, ObjectIdField):
return str(data)
elif isinstance(field, DecimalField):
return data
else:
return str(data)
class Portfolio(Document):
meta = {'collection': 'Portfolios'}
PortfolioName = StringField()
LastUpdateDate = DateTimeField(default=datetime.datetime.now())
RecentActivity = ListField(default=[])
def to_dict(self):
return mongo_to_dict(self, [])
现在,当我创建一个投资组合对象这样
a = Portfolio(PortfolioName='BB Visa').save()
,当我试图让to_dict()
repressentation像a.to_dict()
对象,它完美的作品。
{'_id': '5581cf9129e457241a32e8f7', 'PortfolioName': 'BB Visa', 'RecentActivity': [], 'LastUpdateDate': 1434570641000.0}
但问题是我想要to_dict()
在类级别而不是对象级别上操作。
所以,当我试图这样定义
class Portfolio(Document):
meta = {'collection': 'Portfolios'}
PortfolioName = StringField()
LastUpdateDate = DateTimeField(default=datetime.datetime.now())
RecentActivity = ListField(default=[])
@queryset_manager
def to_dict(self, queryset):
return mongo_to_dict(self, [])
自定义查询集现在运行以下命令Portfolio.to_dict()
产生像下面 回溯错误(最新最后调用):
File "/home/ajay/PycharmProjects/solveit/test.py", line 102, in <module>
print(Portfolio.to_dict())
File "/home/ajay/.pyenv/versions/3.4.3/lib/python3.4/site-packages/mongoengine/queryset/manager.py", line 43, in __get__
queryset = self.get_queryset(owner, queryset)
File "/home/ajay/PycharmProjects/solveit/test.py", line 83, in to_dict
return mongo_to_dict(self, [])
File "/home/ajay/PycharmProjects/solveit/test.py", line 28, in mongo_to_dict
data = obj._data[field_name]
TypeError: 'member_descriptor' object is not subscriptable
我明白QuerySet Manager将类传递给函数,这就是错误的原因。如何解决这个问题。