只需重写PhoneNumber 构造函数,这样您就可以通过Contact 构造函数将字典作为kwargs 传递给它的构造函数。
class PhoneNumber(ndb.Model):
phone_type = ndb.StringProperty(
choices=('home', 'work', 'fax', 'mobile', 'other'))
number = ndb.StringProperty()
def __init__(self, *args, **kwargs):
super(PhoneNumber, self).__init__(*args, **kwargs)
self.__dict__.update(kwargs)
class Contact(ndb.Model):
name = ndb.StringProperty()
birth_day = ndb.DateProperty()
address = ndb.StringProperty()
phone_numbers = ndb.StructuredProperty(PhoneNumber, repeated=True)
company_title = ndb.StringProperty()
company_name = ndb.StringProperty()
company_description = ndb.TextProperty()
company_address = ndb.StringProperty()
def __init__(self, *args, **kwargs):
super(Contact, self).__init__(*args, **kwargs)
if kwargs:
self.phone_numbers = []
for kwarg in kwargs.pop('phone_numbers'):
if isinstance(kwarg, PhoneNumber):
self.phone_numbers.append(kwarg)
else:
p = PhoneNumber(**kwarg)
self.phone_numbers.append(p)
通过这种方式,您可以将PhoneNumber 实体的字典表示传递给Contact 构造函数,或者将PhoneNumber 属性的字典表示传递给PhoneNumber 构造函数。
这是我通过dev_appserver.py的交互式控制台尝试的几个测试用例:
from google.appengine.ext import ndb
from models import Contact, PhoneNumber
kwargs = {
'phone_numbers': [{
'phone_type': 'home',
'number': '123',
}, {
'phone_type': 'work',
'number': '456',
}, {
'phone_type': 'fax',
'number': '789',
}]
}
c = Contact(**kwargs)
print 'Test Case 1:'
print c
print
kwargs = {
'phone_numbers': [
PhoneNumber(**{'phone_type': 'home','number': '123'}),
PhoneNumber(**{'phone_type': 'work','number': '456'}),
PhoneNumber(**{'phone_type': 'fax', 'number': '789'})
]
}
c = Contact(**kwargs)
print 'Test Case 2:'
print c
print
c = Contact(
phone_numbers=[
PhoneNumber(phone_type='home', number='123'),
PhoneNumber(phone_type='work', number='456'),
PhoneNumber(phone_type='fax', number='789')
]
)
print 'Test Case 3:'
print c
print
输出:
Test Case 1:
Contact(phone_numbers=[PhoneNumber(number='123', phone_type='home'),
PhoneNumber(number='456', phone_type='work'),
PhoneNumber(number='789', phone_type='fax')])
Test Case 2:
Contact(phone_numbers=[PhoneNumber(number='123', phone_type='home'),
PhoneNumber(number='456', phone_type='work'),
PhoneNumber(number='789', phone_type='fax')])
Test Case 3:
Contact(phone_numbers=[PhoneNumber(number='123', phone_type='home'),
PhoneNumber(number='456', phone_type='work'),
PhoneNumber(number='789', phone_type='fax')])
正如预期的那样,每种情况都会引发相同的 Contact 对象。