【问题标题】:Run value through function通过函数运行价值
【发布时间】:2017-03-20 10:42:22
【问题描述】:

我在 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) 而不是原始值-我该怎么做?

【问题讨论】:

    标签: python django python-3.6


    【解决方案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 来看,您应该使用元组而不是列表 - 列表应该是位置不重要的同质集合,元组是位置重要的异质集合。在您的情况下,位置确实很重要,因为第一项是结果字典的关键,第二项是转换函数。

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

    【讨论】:

    • 效果很好,谢谢!我唯一需要改变的是在元组中使用self.convert_DOB 而不仅仅是convert_DOB
    • 在映射中直接使用函数绝对是更好的方法,我删除我的答案。
    猜你喜欢
    • 1970-01-01
    • 2014-01-03
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    相关资源
    最近更新 更多