Python 将*任何csv列格式转换为Django格式

Python 将*任何csv列格式转换为Django格式,python,django,csv,Python,Django,Csv,我的代码目前已硬编码为仅接受列格式的csv文件: 名、姓、电话、电子邮件、地址、公司 但是,我希望用户能够上传任何*格式顺序和命名方案的csv文件,并正确填充我们的表单。例如: 电子邮件、姓、名、公司、电话、地址 将是有效的列格式。我该怎么做呢相关代码如下: dr = csv.reader(open(tmp_file,'r')) data_dict = {} headers = next(dr) print (headers)

我的代码目前已硬编码为仅接受列格式的csv文件:

名、姓、电话、电子邮件、地址、公司

但是,我希望用户能够上传任何*格式顺序和命名方案的csv文件,并正确填充我们的表单。例如:

电子邮件、姓、名、公司、电话、地址

将是有效的列格式。我该怎么做呢相关代码如下:

        dr = csv.reader(open(tmp_file,'r')) 
        data_dict = {}

        headers = next(dr)
        print (headers)

        #skips over first line in csv
        iterlines = iter(dr) 
        next(iterlines)
        for row in iterlines:

            data_dict["first_name"] = row[0]
            #print(data_dict["first_name"])
            data_dict["last_name"] = row[1]
            #print(data_dict["last_name"])
            data_dict["phone"] = row[2]
            #print(data_dict["phone"])
            data_dict["email"] = row[3]
            #print(data_dict["email"])
            data_dict["address"] = row[4]
            #print(data_dict["address"])
            data_dict["company"] = row[5]
            #print(data_dict["company"])      
            #adds to form
            try:
                form = AddContactForm(data_dict)
                if form.is_valid():  
                     obj = form.save(commit=False)
                     obj.owner = request.user.username
                     first_name = form.cleaned_data.get(data_dict["first_name"])
                     last_name = form.cleaned_data.get(data_dict["last_name"])
                     phone = form.cleaned_data.get(data_dict["phone"])
                     email = form.cleaned_data.get(data_dict["email"])
                     address = form.cleaned_data.get(data_dict["address"])
                     company = form.cleaned_data.get(data_dict["company"])
                     obj.save() 
                else:
                 logging.getLogger("error_logger").error(form.errors.as_json())   

            except Exception as e:
                logging.getLogger("error_logger").error(repr(e))                    
                pass
现在您可以使用headers\u map来获取row元素

row[headers_map['first_name']]
编辑:为那些爱一行的人

headers_map = {column_name: i for i, column_name in enumerate(headers.split(','))}
现在您可以使用headers\u map来获取row元素

row[headers_map['first_name']]
编辑:为那些爱一行的人

headers_map = {column_name: i for i, column_name in enumerate(headers.split(','))}

有许多方法可以处理文件中不一致的头名称。最好的方法是通过在上传时拒绝这些文件,强制上传者纠正它们来防止这种情况。假设这是不可能的,您可以尝试将提供的头转换为您想要的

import csv
import io
import re

with open(tmp_file, 'r') as f:
    reader = csv.reader  
    headers = next(reader)
# Make a new header list with placeholders
fixed_headers = [None * len(headers)]


for i, value in enumerate(headers) 
    fixed = re.sub(r'(\w+)(?<=[a-z])([A-Z]\w+)', r'\1_\2', v).lower()
    new_headers[i] = fixed
用于将行作为映射到标题的值的字典获取

dr = csv.DictReader(new_file) 

for data_dict in dr:

    #adds to form
    try:
        form = AddContactForm(data_dict)
        if form.is_valid():  
             obj = form.save(commit=False)
             obj.owner = request.user.username
             first_name = form.cleaned_data.get(data_dict["first_name"])
             last_name = form.cleaned_data.get(data_dict["last_name"])
             phone = form.cleaned_data.get(data_dict["phone"])
             email = form.cleaned_data.get(data_dict["email"])
             address = form.cleaned_data.get(data_dict["address"])
             company = form.cleaned_data.get(data_dict["company"])
             obj.save() 
        else:
         logging.getLogger("error_logger").error(form.errors.as_json())   

    except Exception as e:
        logging.getLogger("error_logger").error(repr(e))                    
        pass

有许多方法可以处理文件中不一致的头名称。最好的方法是通过在上传时拒绝这些文件,强制上传者纠正它们来防止这种情况。假设这是不可能的,您可以尝试将提供的头转换为您想要的

import csv
import io
import re

with open(tmp_file, 'r') as f:
    reader = csv.reader  
    headers = next(reader)
# Make a new header list with placeholders
fixed_headers = [None * len(headers)]


for i, value in enumerate(headers) 
    fixed = re.sub(r'(\w+)(?<=[a-z])([A-Z]\w+)', r'\1_\2', v).lower()
    new_headers[i] = fixed
用于将行作为映射到标题的值的字典获取

dr = csv.DictReader(new_file) 

for data_dict in dr:

    #adds to form
    try:
        form = AddContactForm(data_dict)
        if form.is_valid():  
             obj = form.save(commit=False)
             obj.owner = request.user.username
             first_name = form.cleaned_data.get(data_dict["first_name"])
             last_name = form.cleaned_data.get(data_dict["last_name"])
             phone = form.cleaned_data.get(data_dict["phone"])
             email = form.cleaned_data.get(data_dict["email"])
             address = form.cleaned_data.get(data_dict["address"])
             company = form.cleaned_data.get(data_dict["company"])
             obj.save() 
        else:
         logging.getLogger("error_logger").error(form.errors.as_json())   

    except Exception as e:
        logging.getLogger("error_logger").error(repr(e))                    
        pass

这与顺序有关(谢谢),但是有没有一种方法也可以得到类似的字符串?比如,如果他们的csv文件中有“FirstName”列,它仍然适合字段“first_name”?我为FirstName这样的情况添加了一个简单的转换。如果您的需求更复杂,那么您可能需要问一个新问题。我正在尝试运行新代码,但我收到一个错误:fixed=re.sub(r'(\w+)(?)这可以按顺序工作(谢谢),但是有办法也可以获得类似的字符串吗?例如,如果他们的csv文件有“FirstName”列它仍然适用于字段“first_name”?我已经为FirstName这样的情况添加了一个简单的转换。如果您的需求更复杂,那么您可能需要问一个新问题。我正在尝试运行新代码,但我收到了错误:fixed=re.sub(r'(\w+)(?)?