Để có được một as_dict
phương thức trên tất cả các lớp của mình, tôi đã sử dụng một Mixin
lớp sử dụng các kỹ thuật được mô tả bởi Ants Aasma .
class BaseMixin(object):
def as_dict(self):
result = {}
for prop in class_mapper(self.__class__).iterate_properties:
if isinstance(prop, ColumnProperty):
result[prop.key] = getattr(self, prop.key)
return result
Và sau đó sử dụng nó như thế này trong các lớp học của bạn
class MyClass(BaseMixin, Base):
pass
Bằng cách đó, bạn có thể gọi như sau trên một phiên bản của MyClass
.
> myclass = MyClass()
> myclass.as_dict()
Hi vọng điêu nay co ich.
Tôi đã chơi arround với điều này xa hơn một chút, tôi thực sự cần phải hiển thị các phiên bản của mình dict
dưới dạng một đối tượng HAL với các liên kết của nó đến các đối tượng liên quan. Vì vậy, tôi đã thêm phép thuật nhỏ này ở đây, nó sẽ thu thập thông tin trên tất cả các thuộc tính của lớp giống như ở trên, với sự khác biệt là tôi sẽ thu thập dữ liệu sâu hơn vào Relaionship
các thuộc tính và tạo ra links
các thuộc tính này tự động.
Xin lưu ý rằng điều này sẽ chỉ hoạt động đối với các mối quan hệ có một khóa chính duy nhất
from sqlalchemy.orm import class_mapper, ColumnProperty
from functools import reduce
def deepgetattr(obj, attr):
"""Recurses through an attribute chain to get the ultimate value."""
return reduce(getattr, attr.split('.'), obj)
class BaseMixin(object):
def as_dict(self):
IgnoreInstrumented = (
InstrumentedList, InstrumentedDict, InstrumentedSet
)
result = {}
for prop in class_mapper(self.__class__).iterate_properties:
if isinstance(getattr(self, prop.key), IgnoreInstrumented):
# All reverse relations are assigned to each related instances
# we don't need to link these, so we skip
continue
if isinstance(prop, ColumnProperty):
# Add simple property to the dictionary with its value
result[prop.key] = getattr(self, prop.key)
if isinstance(prop, RelationshipProperty):
# Construct links relaions
if 'links' not in result:
result['links'] = {}
# Get value using nested class keys
value = (
deepgetattr(
self, prop.key + "." + prop.mapper.primary_key[0].key
)
)
result['links'][prop.key] = {}
result['links'][prop.key]['href'] = (
"/{}/{}".format(prop.key, value)
)
return result
__table__.columns
sẽ cung cấp cho bạn tên trường SQL, không phải tên thuộc tính mà bạn đã sử dụng trong định nghĩa ORM của mình (nếu hai tên khác nhau).