运行 通过函数取值
Run value through function
我在 Django 中有以下管理命令,它使用来自外部源的数据更新记录:
class Command(BaseCommand):
def handle(self, *args, **options):
field_mappings = {
'first_name': 'Voornaam',
'initials': 'Voorletters',
'last_name_prefix': 'Voorvoegsel',
'last_name': 'Achternaam',
'sex': 'Geslacht',
'DOB': ['Geboortedatum', 'convert_DOB'],
'street': 'Straat',
'house_number': 'Huisnummer',
'zipcode': 'Postcode',
'city': 'Woonplaats',
'country': 'Land',
'phone_number': 'Telefoonnummer',
'phone_number_mobile': 'MobielTelefoonnummer',
'email_address': 'Emailadres',
'insurer_name': 'NaamVerzekeraar',
'insurance_policy_number': 'PolisnummerVerzekering',
'gp_name': 'NaamHuisarts',
}
patients = Patient.objects.all()
for patient in patients:
result = Query(patient.pharmacy, 'patient_by_bsn', {'BSN': patient.BSN}).run()
for x, y in field_mappings.items():
if type(y) == list:
pass
else:
setattr(patient, x, result[y]['0'])
patient.save()
print('Patient {}-{} updated'.format(patient.pharmacy.vv_id, patient.vv_id))
@staticmethod
def convert_DOB(value):
return timezone.datetime.utcfromtimestamp(value).date()
大多数字段无需先转换数据即可保存,但某些字段(如 DOB)需要转换(在本例中,从 UNIX 时间戳转换为 Python datetime.date
)。当前在 if type(y) == list
下面说 pass
我想先通过列出的函数 运行 值,这样它会保存 convert_DOB(value)
而不是原始值 - 我该怎么做这个?
首先在您的映射中不要使用转换函数的名称,而是使用函数本身,即:
def convert_DOB(dob):
# your code here
# ...
field_mappings = {
# ...
'DOB': ['Geboortedatum', convert_DOB],
# ...
}
然后您只需将您的值传递给函数并检索结果:
for attrname, sourcekey in field_mappings.items():
if isinstance(sourcekey, list):
# unpack the list (assumes length 2)
sourcekey, converter = key
value = result[sourcekey]['0']
# convert the value
value = converter(value)
else:
# no conversion needed
value = result[sourcekey]['0']
# done
setattr(patient, attrname, value)
请注意,从纯语义 POV 来看,您应该使用元组而不是列表 - 列表应该是位置不重要的同质集合,元组是位置重要的异构集合。在您的情况下,位置确实很重要,因为第一项是结果字典的关键,第二项是转换函数。
此外,您使用 field_mappings
的方式建议您可以将其替换为 (attrname, key_or_key_converter) 元组列表,因为您只迭代字典的 (key, value) 对。
我在 Django 中有以下管理命令,它使用来自外部源的数据更新记录:
class Command(BaseCommand):
def handle(self, *args, **options):
field_mappings = {
'first_name': 'Voornaam',
'initials': 'Voorletters',
'last_name_prefix': 'Voorvoegsel',
'last_name': 'Achternaam',
'sex': 'Geslacht',
'DOB': ['Geboortedatum', 'convert_DOB'],
'street': 'Straat',
'house_number': 'Huisnummer',
'zipcode': 'Postcode',
'city': 'Woonplaats',
'country': 'Land',
'phone_number': 'Telefoonnummer',
'phone_number_mobile': 'MobielTelefoonnummer',
'email_address': 'Emailadres',
'insurer_name': 'NaamVerzekeraar',
'insurance_policy_number': 'PolisnummerVerzekering',
'gp_name': 'NaamHuisarts',
}
patients = Patient.objects.all()
for patient in patients:
result = Query(patient.pharmacy, 'patient_by_bsn', {'BSN': patient.BSN}).run()
for x, y in field_mappings.items():
if type(y) == list:
pass
else:
setattr(patient, x, result[y]['0'])
patient.save()
print('Patient {}-{} updated'.format(patient.pharmacy.vv_id, patient.vv_id))
@staticmethod
def convert_DOB(value):
return timezone.datetime.utcfromtimestamp(value).date()
大多数字段无需先转换数据即可保存,但某些字段(如 DOB)需要转换(在本例中,从 UNIX 时间戳转换为 Python datetime.date
)。当前在 if type(y) == list
下面说 pass
我想先通过列出的函数 运行 值,这样它会保存 convert_DOB(value)
而不是原始值 - 我该怎么做这个?
首先在您的映射中不要使用转换函数的名称,而是使用函数本身,即:
def convert_DOB(dob):
# your code here
# ...
field_mappings = {
# ...
'DOB': ['Geboortedatum', convert_DOB],
# ...
}
然后您只需将您的值传递给函数并检索结果:
for attrname, sourcekey in field_mappings.items():
if isinstance(sourcekey, list):
# unpack the list (assumes length 2)
sourcekey, converter = key
value = result[sourcekey]['0']
# convert the value
value = converter(value)
else:
# no conversion needed
value = result[sourcekey]['0']
# done
setattr(patient, attrname, value)
请注意,从纯语义 POV 来看,您应该使用元组而不是列表 - 列表应该是位置不重要的同质集合,元组是位置重要的异构集合。在您的情况下,位置确实很重要,因为第一项是结果字典的关键,第二项是转换函数。
此外,您使用 field_mappings
的方式建议您可以将其替换为 (attrname, key_or_key_converter) 元组列表,因为您只迭代字典的 (key, value) 对。