簡體   English   中英

使用python DictReader將CSV讀入Django模型時出現問題

[英]Trouble reading CSV into Django models with python DictReader

我正在使用Cloud9(據我所讀,目前使用Python 2.6,而不是Python 3)編寫Django應用。 我正在嘗試使用DictReader讀取CSV文件,並使用CSV中的每一列來創建模型的新實例並填充模型字段。

views.py

class GenerateFromCSV(CreateView):
    model = group
    template_name = "my_app/csv_generate.html"
    def form_valid(self, form):
        new_group = form.save()
        the_csv = open(new_group.group_csv, 'rbU')
        fieldnames = ['c_type', 'f_name', 'q_type', 'ans', 'n_questions', 'bucket']
        data_file = csv.DictReader(the_csv, fieldnames = fieldnames, delimiter=',', dialect=csv.excel)
        for row in data_file:
            new_card = Card(
                name = 'card',
                card_type = row['c_type'], 
                file_name = row['f_name'], 
                question_type = row['q_type'], 
                answer = row['ans'], 
                num_questions = row['n_questions'], 
                bucket = row['bucket'],
                exam = new_exam)
            new_card.save()

models.py

class Group(models.Model):
    name = models.CharField(max_length=255, blank = True)
    subject = models.CharField(max_length=255, choices = SUBJECT, blank = True)
    num_questions = models.IntegerField(default=0, blank = True, null = True)
    group_csv = models.FileField(upload_to='csv', blank = True, null = True)
    def __unicode__(self):
        return self.name

class Card(models.Model):
    name = models.CharField(max_length=255, blank = True)
    #ordered same as column order in CSV
    card_type = models.CharField(max_length=255, choices = CARDTYPE, blank = True)
    file_name = models.CharField(max_length=255, blank = True)
    question_type = models.IntegerField(default = 0, blank = True, null = True)
    answer = models.IntegerField(max_length = 1, choices = ANSWERS, blank = True, null = True)
    num_questions = models.IntegerField(default = 0, blank = True, null = True)
    bucket = models.CharField(max_length=255, blank = True)
    exam = models.ForeignKey(Exam)
    def __unicode__(self):
        return self.name or 'card'

使用上面的代碼,當我在CSV上調用open()時,出現TypeError(強制轉換為Unicode:需要字符串或緩沖區,找到了FieldFile)。 如果取消對open()的調用,則會收到錯誤消息:“在未加引號的字段中出現換行符-您是否需要在通用換行模式下打開文件?”

我的CSV格式為(並非每一列的每一行都包含數據):

3,the_file_name.png,0,"00001",,Equations

正確的語法是什么?

編輯這是我的堆棧跟蹤:

Traceback:
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/core/handlers/base.py" in get_response
  115.                         response = callback(request, *callback_args, **callback_kwargs)
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/base.py" in dispatch
  86.         return handler(request, *args, **kwargs)
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/edit.py" in post
  199.         return super(BaseCreateView, self).post(request, *args, **kwargs)
File "/usr/libexec/openshift/cartridges/c9-0.1/root/python2.6.6/site-packages/Django-1.5-py2.6.egg/django/views/generic/edit.py" in post
  165.             return self.form_valid(form)
File "/var/lib/stickshift/52a55ef4e0b8cde0ff000036/app-root/data/705411/zamrdjango/zamr/views.py" in form_valid
  35.         with new_exam.exam_csv.open('rbU') as the_csv:

Exception Type: AttributeError at /import/
Exception Value: 'NoneType' object has no attribute '__exit__'

請查看FileField的文檔,因為問題是您沒有將文件名傳遞給文件open功能:
https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.fields.files.FieldFile

您的代碼可能是:

class GenerateFromCSV(CreateView):
    model = group
    template_name = "my_app/csv_generate.html"
    def form_valid(self, form):
        new_group = form.save()
        with new_group.group_csv.open('rbU') as the_csv:
            fieldnames = ['c_type', 'f_name', 'q_type', 'ans', 'n_questions', 'bucket']
            data_file = csv.DictReader(the_csv, fieldnames = fieldnames, delimiter=',', dialect=csv.excel)
            for row in data_file:
                new_card = Card(
                    name = 'item',
                    card_type = row['c_type'], 
                    file_name = row['f_name'], 
                    question_type = row['q_type'], 
                    answer = row['ans'], 
                    num_questions = row['n_questions'], 
                    bucket = row['bucket'],
                    exam = new_exam)
                new_card.save()

好吧,我最終通過在csv上調用.read() ,然后調用.splitlines()來獲取每一行的行和列來修復它。 這是我的新views.py:

def form_valid(self, form):
    new_group = form.save()
    print(new_exam.exam_csv.name)
    data = new_group.group_csv.read()
    rows = data.splitlines()
    for row in rows:
        columns = row.split(',')
        print(columns)
        new_card = Card(
            name = columns[0],
            card_type = columns[0], 
            file_name = columns[1], 
            question_type = int(columns[2]),
            answer = columns[3].replace('"', '').strip(), 
            num_questions = columns[4], 
            bucket = columns[5],
            group = new_group)
        print(new_card.name)
        new_card.save()

我確定這不是正確的語法或約定,仍然有一些要弄清楚的事情(例如列名),但目前它已將所有信息正確地解析為正確的模型字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM