通过功能运行值

时间:2017-03-20 10:42:23

标签: python django python-3.6

我在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)。它当前在pass下面显示if type(y) == list的位置我希望首先通过列出的函数运行值,以便保存convert_DOB(value)而不是原始值 - 我该怎么做?

1 个答案:

答案 0 :(得分:1)

首先在映射中不要使用转换函数的名称,而是使用函数本身,即:

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开始,您应该使用元组而不是列表 - 列表应该是位置不重要的同质集合,元组是异质集合,其中poistion很重要。在你的情况下,位置确实很重要,因为第一项是结果dict的关键,第二项是转换函数的关键。

此外,您使用field_mappings的方式建议您可以用(attrname,key_or_key_converter)元组列表替换它,因为您只迭代dict的(键,值)对。